--- /dev/null
+// -*- C++ -*-
+// $Id: aboutdlg.cpp,v 1.2 2010-01-17 21:57:00 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+
+#include "aboutdlg.h"
+#include "appname.h"
+#include "upgrade.h"
+
+AboutDlg::AboutDlg(QWidget *parent, const QString &ver1,
+ const QString &ver2): QDialog(parent)
+{
+ ui.setupUi(this);
+ QTextDocument *doc = ui.textEdit->document();
+ ui.textEdit->setReadOnly(true);
+ QString tt = doc->toHtml();
+ tt.replace(QRegExp("\\$appname\\$"), QString(appName));
+ tt.replace(QRegExp("\\$babelversion\\$"), ver1);
+ tt.replace(QRegExp("\\$babelfeversion\\$"), ver2);
+
+ // Not localized as it should never be seen.
+ tt.replace(QRegExp("\\$upgradetestmode\\$"),
+ UpgradeCheck::isTestMode() ? "**Upgrade test mode**" : "");
+
+ doc->setHtml(tt);
+ QTextCursor cur(doc);
+ cur.setPosition(0);
+ ui.textEdit->setTextCursor(cur);
+ ui.textEdit->ensureCursorVisible();
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: aboutdlg.cpp,v 1.2 2010-01-17 21:57:00 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-
-#include "aboutdlg.h"
-#include "appname.h"
-#include "upgrade.h"
-
-AboutDlg::AboutDlg(QWidget *parent, const QString &ver1,
- const QString &ver2): QDialog(parent)
-{
- ui.setupUi(this);
- QTextDocument *doc = ui.textEdit->document();
- ui.textEdit->setReadOnly(true);
- QString tt = doc->toHtml();
- tt.replace(QRegExp("\\$appname\\$"), QString(appName));
- tt.replace(QRegExp("\\$babelversion\\$"), ver1);
- tt.replace(QRegExp("\\$babelfeversion\\$"), ver2);
-
- // Not localized as it should never be seen.
- tt.replace(QRegExp("\\$upgradetestmode\\$"),
- UpgradeCheck::isTestMode() ? "**Upgrade test mode**" : "");
-
- doc->setHtml(tt);
- QTextCursor cur(doc);
- cur.setPosition(0);
- ui.textEdit->setTextCursor(cur);
- ui.textEdit->ensureCursorVisible();
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: advdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+#include <QMessageBox>
+#include <QProcess>
+#include <QFileDialog>
+#include <QSettings>
+#include "advdlg.h"
+
+//------------------------------------------------------------------------
+AdvDlg::AdvDlg(QWidget* parent,
+ bool &synthShortNames,
+ bool &enableCharSetXform,
+ bool &previewGmap,
+ int &debugLevel):
+ QDialog(parent),
+ synthShortNames(synthShortNames),
+ enableCharSetXform(enableCharSetXform),
+ previewGmap(previewGmap),
+ debugLevel(debugLevel)
+{
+ ui.setupUi(this);
+ ui.synthShortNames->setChecked(synthShortNames);
+ ui.enableCharSetXform->setChecked(enableCharSetXform);
+ ui.previewGmap->setChecked(previewGmap);
+ ui.debugCombo->setCurrentIndex(debugLevel+1);
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
+ ui.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
+}
+
+void AdvDlg::acceptClicked()
+{
+ synthShortNames = ui.synthShortNames->isChecked();
+ enableCharSetXform = ui.enableCharSetXform->isChecked();
+ previewGmap = ui.previewGmap->isChecked();
+ debugLevel = ui.debugCombo->currentIndex()-1;
+ accept();
+}
+
+void AdvDlg::rejectClicked()
+{
+ reject();
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: advdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-#include <QMessageBox>
-#include <QProcess>
-#include <QFileDialog>
-#include <QSettings>
-#include "advdlg.h"
-
-//------------------------------------------------------------------------
-AdvDlg::AdvDlg(QWidget* parent,
- bool &synthShortNames,
- bool &enableCharSetXform,
- bool &previewGmap,
- int &debugLevel):
- QDialog(parent),
- synthShortNames(synthShortNames),
- enableCharSetXform(enableCharSetXform),
- previewGmap(previewGmap),
- debugLevel(debugLevel)
-{
- ui.setupUi(this);
- ui.synthShortNames->setChecked(synthShortNames);
- ui.enableCharSetXform->setChecked(enableCharSetXform);
- ui.previewGmap->setChecked(previewGmap);
- ui.debugCombo->setCurrentIndex(debugLevel+1);
- ui.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
- ui.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
- connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
- connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
-}
-
-void AdvDlg::acceptClicked()
-{
- synthShortNames = ui.synthShortNames->isChecked();
- enableCharSetXform = ui.enableCharSetXform->isChecked();
- previewGmap = ui.previewGmap->isChecked();
- debugLevel = ui.debugCombo->currentIndex()-1;
- accept();
-}
-
-void AdvDlg::rejectClicked()
-{
- reject();
-}
FORMS += version_mismatch.ui
FORMS += wayptsui.ui
-SOURCES += aboutdlg.cpp
-SOURCES += advdlg.cpp
-SOURCES += donate.cpp
-SOURCES += dpencode.cpp
-SOURCES += filterdata.cpp
-SOURCES += filterdlg.cpp
-SOURCES += filterwidgets.cpp
-SOURCES += format.cpp
-SOURCES += formatload.cpp
-SOURCES += gmapdlg.cpp
-SOURCES += gpx.cpp
-SOURCES += help.cpp
-SOURCES += latlng.cpp
-SOURCES += main.cpp
-SOURCES += mainwindow.cpp
-SOURCES += map.cpp
-SOURCES += optionsdlg.cpp
-SOURCES += preferences.cpp
-SOURCES += processwait.cpp
-SOURCES += upgrade.cpp
-SOURCES += version_mismatch.cpp
-macx:SOURCES += serial_mac.cpp
-unix:SOURCES += serial_unix.cpp
-windows:SOURCES += serial_win.cpp
+SOURCES += aboutdlg.cc
+SOURCES += advdlg.cc
+SOURCES += donate.cc
+SOURCES += dpencode.cc
+SOURCES += filterdata.cc
+SOURCES += filterdlg.cc
+SOURCES += filterwidgets.cc
+SOURCES += format.cc
+SOURCES += formatload.cc
+SOURCES += gmapdlg.cc
+SOURCES += gpx.cc
+SOURCES += help.cc
+SOURCES += latlng.cc
+SOURCES += main.cc
+SOURCES += mainwindow.cc
+SOURCES += map.cc
+SOURCES += optionsdlg.cc
+SOURCES += preferences.cc
+SOURCES += processwait.cc
+SOURCES += upgrade.cc
+SOURCES += version_mismatch.cc
+macx:SOURCES += serial_mac.cc
+unix:SOURCES += serial_unix.cc
+windows:SOURCES += serial_win.cc
HEADERS += aboutdlg.h
HEADERS += advdlg.h
--- /dev/null
+// -*- C++ -*-
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+
+#include "donate.h"
+#include <QUrl>
+#include <QDesktopServices>
+
+// A completely simple QDialog, in a class of its own for layout.
+Donate::Donate(QWidget *parent) : QDialog(parent)
+{
+ ui.setupUi(this);
+ connect(ui.contributeButton, SIGNAL(clicked()), this, SLOT(contributeClicked()));
+}
+
+void Donate::contributeClicked()
+{
+ QDesktopServices::openUrl(QUrl("http://www.gpsbabel.org/contribute.html"));
+ close();
+}
+++ /dev/null
-// -*- C++ -*-
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-
-#include "donate.h"
-#include <QUrl>
-#include <QDesktopServices>
-
-// A completely simple QDialog, in a class of its own for layout.
-Donate::Donate(QWidget *parent) : QDialog(parent)
-{
- ui.setupUi(this);
- connect(ui.contributeButton, SIGNAL(clicked()), this, SLOT(contributeClicked()));
-}
-
-void Donate::contributeClicked()
-{
- QDesktopServices::openUrl(QUrl("http://www.gpsbabel.org/contribute.html"));
- close();
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: dpencode.cpp,v 1.3 2009-09-08 16:06:32 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Original in JavaScript:
+// PolylineEncoder.js copyright Mark McClure April/May 2007
+//
+// Translated to C++
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include <stack>
+#include <math.h>
+#include "dpencode.h"
+
+using std::vector;
+using std::stack;
+using std::string;
+
+
+
+//------------------------------------------------------------------------
+PolylineEncoder::PolylineEncoder(int numLevels, double zoomFactor, double vs):
+ numLevels(numLevels), zoomFactor(zoomFactor), verySmall(vs)
+{
+ if (verySmall <=0.0)
+ verySmall = 1.0E-5;
+ for(int i = 0; i < numLevels; i++)
+ zoomLevelBreaks.push_back(verySmall*pow(zoomFactor, numLevels-i-1));
+}
+
+//------------------------------------------------------------------------
+class IntervalPair
+{
+public:
+ IntervalPair(int i0, int i1): i0(i0), i1(i1) {
+ }
+ int i0, i1;
+};
+
+//------------------------------------------------------------------------
+static double hypotenuse(double a, double b){
+ return sqrt(a*a + b*b);
+}
+//------------------------------------------------------------------------
+static double hdist(const LatLng &a, const LatLng &b) {
+ return hypotenuse(a.lat()-b.lat(), a.lng()-b.lng());
+}
+
+//------------------------------------------------------------------------
+static string encodeNumber(int num)
+{
+ string encodeString = "";
+ while (num >= 0x20) {
+ encodeString += char((0x20 | (num & 0x1f)) + 63);
+ num = num >> 5;
+ }
+ encodeString += char(num + 63);
+ return encodeString;
+}
+
+//------------------------------------------------------------------------
+// This one is Google's verbatim.
+static string encodeSignedNumber (int num)
+{
+ int sgn_num = num << 1;
+ if (num < 0) {
+ sgn_num = ~(sgn_num);
+ }
+ return(encodeNumber(sgn_num));
+}
+
+//------------------------------------------------------------------------
+int roundToInt(double x) {
+ return (x>0.0) ? int(x+0.5) : int(x-0.5);
+}
+//------------------------------------------------------------------------
+void PolylineEncoder::createEncodings(string &encoded_points,
+ const vector <LatLng> &points,
+ const vector <double> &dists)
+{
+ encoded_points = "";;
+ int plat = 0;
+ int plng = 0;
+ for(unsigned int i = 0; i < points.size(); i++) {
+ if(dists[i] >= 0.0 || i == 0 || i == points.size()-1) {
+ int late5 = roundToInt(points[i].lat() * 1e5);
+ int lnge5 = roundToInt(points[i].lng() * 1e5);
+ int dlat = late5 - plat;
+ int dlng = lnge5 - plng;
+ encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
+ plat = late5;
+ plng = lnge5;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// This computes the appropriate zoom level of a point in terms of it's
+// distance from the relevant segment in the DP algorithm. Could be done
+// in terms of a logarithm, but this approach makes it a bit easier to
+// ensure that the level is not too large.
+int PolylineEncoder::computeLevel(double dd)
+{
+ int lev = 0;
+ if(dd > verySmall) {
+ while(dd < zoomLevelBreaks[lev]) {
+ lev++;
+ }
+ }
+ return lev;
+}
+//------------------------------------------------------------------------
+// Now we can use the previous function to march down the list
+// of points and encode the levels. Like createEncodings, we
+// ignore points whose distance (in dists) is undefined.
+void PolylineEncoder::encodeLevels(string &encoded_levels, const vector<LatLng> &points, const vector<double>&dists)
+{
+ encoded_levels = "";
+ encoded_levels += encodeNumber(numLevels-1);
+ for (unsigned int i=1; i<points.size()-1; i++) {
+ if(dists[i] >= 0.0) {
+ encoded_levels += encodeNumber(numLevels-computeLevel(dists[i])-1);
+ }
+ }
+ encoded_levels += encodeNumber(numLevels-1);
+}
+
+
+//------------------------------------------------------------------------
+double PolylineEncoder::distance(const LatLng &p0, const LatLng &p1, const LatLng &p2)
+{
+ double out = 0.0;
+ if (p1.lat() == p2.lat() && p1.lng() == p2.lng()) {
+ out = hdist(p2, p0);
+ }
+ else {
+ double dlat = (p2.lat()-p1.lat());
+ double dlng = (p2.lng()-p1.lng());
+ double u = ((p0.lat()-p1.lat())*dlat+(p0.lng()-p1.lng())*dlng)/(dlat*dlat + dlng*dlng);
+
+ if (u <= 0) {
+ out = hdist(p0, p1);
+ }
+ else if(u >= 1) {
+ out = hdist(p0, p2);
+ }
+ else {
+ out = hdist(p0, LatLng(p1.lat() + u*dlat, p1.lng() + u*dlng));
+ }
+ }
+ return out;
+}
+
+//------------------------------------------------------------------------
+void PolylineEncoder::dpEncode(string &encPts, string &encLevels, const vector<LatLng> &points)
+{
+ if (points.size() < 2) {
+ encPts = encLevels = ""; // no solution here.
+ return;
+
+ }
+ stack <IntervalPair> stk;
+ vector <double> dists(points.size(), -1.0);
+
+ stk.push(IntervalPair(0, int(points.size())-1));
+ while (!stk.empty()) {
+
+ IntervalPair current = stk.top();
+ stk.pop();
+
+ double maxDist = -1.0;
+ int maxLoc = -1;
+ for (int i=current.i0+1; i<current.i1; i++) {
+ double dist = this->distance(points[i], points[current.i0], points[current.i1]);
+ if(dist > maxDist) {
+ maxDist = dist;
+ maxLoc = i;
+ }
+ }
+ if(maxDist > this->verySmall) {
+ dists[maxLoc] = maxDist;
+ stk.push(IntervalPair(current.i0, maxLoc));
+ stk.push(IntervalPair(maxLoc, current.i1));
+ }
+ }
+ createEncodings(encPts, points, dists);
+ encodeLevels(encLevels, points, dists);
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: dpencode.cpp,v 1.3 2009-09-08 16:06:32 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Original in JavaScript:
-// PolylineEncoder.js copyright Mark McClure April/May 2007
-//
-// Translated to C++
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include <stack>
-#include <math.h>
-#include "dpencode.h"
-
-using std::vector;
-using std::stack;
-using std::string;
-
-
-
-//------------------------------------------------------------------------
-PolylineEncoder::PolylineEncoder(int numLevels, double zoomFactor, double vs):
- numLevels(numLevels), zoomFactor(zoomFactor), verySmall(vs)
-{
- if (verySmall <=0.0)
- verySmall = 1.0E-5;
- for(int i = 0; i < numLevels; i++)
- zoomLevelBreaks.push_back(verySmall*pow(zoomFactor, numLevels-i-1));
-}
-
-//------------------------------------------------------------------------
-class IntervalPair
-{
-public:
- IntervalPair(int i0, int i1): i0(i0), i1(i1) {
- }
- int i0, i1;
-};
-
-//------------------------------------------------------------------------
-static double hypotenuse(double a, double b){
- return sqrt(a*a + b*b);
-}
-//------------------------------------------------------------------------
-static double hdist(const LatLng &a, const LatLng &b) {
- return hypotenuse(a.lat()-b.lat(), a.lng()-b.lng());
-}
-
-//------------------------------------------------------------------------
-static string encodeNumber(int num)
-{
- string encodeString = "";
- while (num >= 0x20) {
- encodeString += char((0x20 | (num & 0x1f)) + 63);
- num = num >> 5;
- }
- encodeString += char(num + 63);
- return encodeString;
-}
-
-//------------------------------------------------------------------------
-// This one is Google's verbatim.
-static string encodeSignedNumber (int num)
-{
- int sgn_num = num << 1;
- if (num < 0) {
- sgn_num = ~(sgn_num);
- }
- return(encodeNumber(sgn_num));
-}
-
-//------------------------------------------------------------------------
-int roundToInt(double x) {
- return (x>0.0) ? int(x+0.5) : int(x-0.5);
-}
-//------------------------------------------------------------------------
-void PolylineEncoder::createEncodings(string &encoded_points,
- const vector <LatLng> &points,
- const vector <double> &dists)
-{
- encoded_points = "";;
- int plat = 0;
- int plng = 0;
- for(unsigned int i = 0; i < points.size(); i++) {
- if(dists[i] >= 0.0 || i == 0 || i == points.size()-1) {
- int late5 = roundToInt(points[i].lat() * 1e5);
- int lnge5 = roundToInt(points[i].lng() * 1e5);
- int dlat = late5 - plat;
- int dlng = lnge5 - plng;
- encoded_points += encodeSignedNumber(dlat) + encodeSignedNumber(dlng);
- plat = late5;
- plng = lnge5;
- }
- }
-}
-
-//------------------------------------------------------------------------
-// This computes the appropriate zoom level of a point in terms of it's
-// distance from the relevant segment in the DP algorithm. Could be done
-// in terms of a logarithm, but this approach makes it a bit easier to
-// ensure that the level is not too large.
-int PolylineEncoder::computeLevel(double dd)
-{
- int lev = 0;
- if(dd > verySmall) {
- while(dd < zoomLevelBreaks[lev]) {
- lev++;
- }
- }
- return lev;
-}
-//------------------------------------------------------------------------
-// Now we can use the previous function to march down the list
-// of points and encode the levels. Like createEncodings, we
-// ignore points whose distance (in dists) is undefined.
-void PolylineEncoder::encodeLevels(string &encoded_levels, const vector<LatLng> &points, const vector<double>&dists)
-{
- encoded_levels = "";
- encoded_levels += encodeNumber(numLevels-1);
- for (unsigned int i=1; i<points.size()-1; i++) {
- if(dists[i] >= 0.0) {
- encoded_levels += encodeNumber(numLevels-computeLevel(dists[i])-1);
- }
- }
- encoded_levels += encodeNumber(numLevels-1);
-}
-
-
-//------------------------------------------------------------------------
-double PolylineEncoder::distance(const LatLng &p0, const LatLng &p1, const LatLng &p2)
-{
- double out = 0.0;
- if (p1.lat() == p2.lat() && p1.lng() == p2.lng()) {
- out = hdist(p2, p0);
- }
- else {
- double dlat = (p2.lat()-p1.lat());
- double dlng = (p2.lng()-p1.lng());
- double u = ((p0.lat()-p1.lat())*dlat+(p0.lng()-p1.lng())*dlng)/(dlat*dlat + dlng*dlng);
-
- if (u <= 0) {
- out = hdist(p0, p1);
- }
- else if(u >= 1) {
- out = hdist(p0, p2);
- }
- else {
- out = hdist(p0, LatLng(p1.lat() + u*dlat, p1.lng() + u*dlng));
- }
- }
- return out;
-}
-
-//------------------------------------------------------------------------
-void PolylineEncoder::dpEncode(string &encPts, string &encLevels, const vector<LatLng> &points)
-{
- if (points.size() < 2) {
- encPts = encLevels = ""; // no solution here.
- return;
-
- }
- stack <IntervalPair> stk;
- vector <double> dists(points.size(), -1.0);
-
- stk.push(IntervalPair(0, int(points.size())-1));
- while (!stk.empty()) {
-
- IntervalPair current = stk.top();
- stk.pop();
-
- double maxDist = -1.0;
- int maxLoc = -1;
- for (int i=current.i0+1; i<current.i1; i++) {
- double dist = this->distance(points[i], points[current.i0], points[current.i1]);
- if(dist > maxDist) {
- maxDist = dist;
- maxLoc = i;
- }
- }
- if(maxDist > this->verySmall) {
- dists[maxLoc] = maxDist;
- stk.push(IntervalPair(current.i0, maxLoc));
- stk.push(IntervalPair(maxLoc, current.i1));
- }
- }
- createEncodings(encPts, points, dists);
- encodeLevels(encLevels, points, dists);
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: filterdata.cpp,v 1.4 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+#include "filterdata.h"
+
+QStringList WayPtsFilterData::makeOptionString()
+{
+ QStringList args;
+ if (!inUse)
+ return args;
+
+ if (radius) {
+ args << QString("-x");
+ args << QString("radius,distance=%1%2,lat=%3,lon=%4")
+ .arg(radiusVal).arg("MK"[radiusUnit]).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
+ }
+ if (duplicates && (shortNames ^ locations)) {
+ args << QString("-x");
+ QString s = "duplicate";
+ if (shortNames)
+ s += ",shortname";
+ if (locations)
+ s += ",location";
+ args << s;
+ }
+
+ if (position) {
+ args << QString("-x");
+ args << QString("position,distance=%1%2").arg(positionVal).arg("FM"[positionUnit]);
+ }
+ return args;
+}
+
+//------------------------------------------------------------------------
+static QString optionDate(const QDateTime &dt, bool useLocal)
+{
+ QDateTime d;
+ if (useLocal) {
+ d = dt.toLocalTime();
+ }
+ else {
+ d = dt.toUTC();
+ }
+
+ QDate date = d.date();
+ QTime time = d.time();
+ QString s = QString("%1%2%3%4%5%6")
+ .arg(date.year(), 4, 10, QChar('0'))
+ .arg(date.month(), 2, 10, QChar('0'))
+ .arg(date.day(), 2, 10, QChar('0'))
+ .arg(time.hour(), 2, 10, QChar('0'))
+ .arg(time.minute(), 2, 10, QChar('0'))
+ .arg(time.second(), 2, 10, QChar('0'));
+ return s;
+}
+
+//------------------------------------------------------------------------
+QStringList TrackFilterData::makeOptionString()
+{
+ static const char *fixStrings[] = {"none", "pps", "dgpss", "3d", "2d"}; // match with designer!
+ QStringList args;
+ if (!inUse)
+ return args;
+
+ QString s;
+ if (GPSFixes) s += QString(",fix=%1").arg(fixStrings[GPSFixesVal]);
+ if (course) s += ",course";
+ if (speed) s += ",speed";
+ if (pack) s += ",pack";
+ if (merge) s += ",merge";
+ if (pack || merge) {
+ if (splitByDate) {
+ s += ",split";
+ }
+ if (splitByTime) {
+ s += ",split";
+ if (splitTime > 0)
+ s += QString("=%1%2").arg(splitTime).arg("mhd"[splitTimeUnit]);
+ }
+ if (splitByDistance && splitDist > 0) {
+ double d = splitDist;
+ char u = ' ';
+ if (splitDistUnit == 0) { // ft.
+ d /= 5280.0; u = 'm';
+ }
+ else if (splitDistUnit == 1) { //m
+ d /= 1000.0; u = 'k';
+ }
+ else if (splitDistUnit == 2) { //km
+ u = 'k';
+ }
+ else if (splitDistUnit == 3) { //m
+ u = 'm';
+ }
+ s += QString(",sdistance=%1%2").arg(d).arg(u);
+ }
+ }
+
+ if (start) s += QString(",start=%1").arg(optionDate(startTime, TZ));
+ if (stop) s += QString(",stop=%1").arg(optionDate(stopTime, TZ));
+ if (move) s += QString(",move=%1d%2h%3m%4s").arg(days).arg(hours).arg(mins).arg(secs);
+ if (title) s += QString(",title=%1").arg(titleString);
+
+ if (s.length())
+ args << "-x" << "track" + s;
+
+ return args;
+}
+
+//------------------------------------------------------------------------
+QStringList RtTrkFilterData::makeOptionString()
+{
+ QStringList args;
+ if (!inUse)
+ return args;
+
+ if (reverse) args << QString("-x") << QString("reverse");
+ if (simplify) args << QString("-x") << QString("simplify,count=%1").arg(limitTo);
+
+ return args;
+}
+
+//------------------------------------------------------------------------
+QStringList MiscFltFilterData::makeOptionString()
+{
+ QStringList args;
+ if (!inUse)
+ return args;
+
+ if (nukeRoutes || nukeTracks || nukeWaypoints) {
+ args << QString("-x");
+ QString s = "nuketypes";
+ if (nukeRoutes) s += ",routes";
+ if (nukeTracks) s += ",tracks";
+ if (nukeWaypoints) s += ",waypoints";
+ args << s;
+ }
+
+ if (swap) args << "-x" << "swap";
+
+ if (transform) {
+ static const char *xformStr[] = {
+ "wpt=trk",
+ "trk=rte",
+ "rte=wpt",
+ "wpt=rte",
+ "rte=trk",
+ "trk=wpt",
+ };
+ args << QString("-x");
+ QString s= QString("transform,%1").arg(xformStr[transformVal]);
+ if (del) s += ",del";
+ args << s;
+ }
+ return args;
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: filterdata.cpp,v 1.4 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-#include "filterdata.h"
-
-QStringList WayPtsFilterData::makeOptionString()
-{
- QStringList args;
- if (!inUse)
- return args;
-
- if (radius) {
- args << QString("-x");
- args << QString("radius,distance=%1%2,lat=%3,lon=%4")
- .arg(radiusVal).arg("MK"[radiusUnit]).arg(latVal, 0, 'f', 8).arg(longVal, 0, 'f', 8);
- }
- if (duplicates && (shortNames ^ locations)) {
- args << QString("-x");
- QString s = "duplicate";
- if (shortNames)
- s += ",shortname";
- if (locations)
- s += ",location";
- args << s;
- }
-
- if (position) {
- args << QString("-x");
- args << QString("position,distance=%1%2").arg(positionVal).arg("FM"[positionUnit]);
- }
- return args;
-}
-
-//------------------------------------------------------------------------
-static QString optionDate(const QDateTime &dt, bool useLocal)
-{
- QDateTime d;
- if (useLocal) {
- d = dt.toLocalTime();
- }
- else {
- d = dt.toUTC();
- }
-
- QDate date = d.date();
- QTime time = d.time();
- QString s = QString("%1%2%3%4%5%6")
- .arg(date.year(), 4, 10, QChar('0'))
- .arg(date.month(), 2, 10, QChar('0'))
- .arg(date.day(), 2, 10, QChar('0'))
- .arg(time.hour(), 2, 10, QChar('0'))
- .arg(time.minute(), 2, 10, QChar('0'))
- .arg(time.second(), 2, 10, QChar('0'));
- return s;
-}
-
-//------------------------------------------------------------------------
-QStringList TrackFilterData::makeOptionString()
-{
- static const char *fixStrings[] = {"none", "pps", "dgpss", "3d", "2d"}; // match with designer!
- QStringList args;
- if (!inUse)
- return args;
-
- QString s;
- if (GPSFixes) s += QString(",fix=%1").arg(fixStrings[GPSFixesVal]);
- if (course) s += ",course";
- if (speed) s += ",speed";
- if (pack) s += ",pack";
- if (merge) s += ",merge";
- if (pack || merge) {
- if (splitByDate) {
- s += ",split";
- }
- if (splitByTime) {
- s += ",split";
- if (splitTime > 0)
- s += QString("=%1%2").arg(splitTime).arg("mhd"[splitTimeUnit]);
- }
- if (splitByDistance && splitDist > 0) {
- double d = splitDist;
- char u = ' ';
- if (splitDistUnit == 0) { // ft.
- d /= 5280.0; u = 'm';
- }
- else if (splitDistUnit == 1) { //m
- d /= 1000.0; u = 'k';
- }
- else if (splitDistUnit == 2) { //km
- u = 'k';
- }
- else if (splitDistUnit == 3) { //m
- u = 'm';
- }
- s += QString(",sdistance=%1%2").arg(d).arg(u);
- }
- }
-
- if (start) s += QString(",start=%1").arg(optionDate(startTime, TZ));
- if (stop) s += QString(",stop=%1").arg(optionDate(stopTime, TZ));
- if (move) s += QString(",move=%1d%2h%3m%4s").arg(days).arg(hours).arg(mins).arg(secs);
- if (title) s += QString(",title=%1").arg(titleString);
-
- if (s.length())
- args << "-x" << "track" + s;
-
- return args;
-}
-
-//------------------------------------------------------------------------
-QStringList RtTrkFilterData::makeOptionString()
-{
- QStringList args;
- if (!inUse)
- return args;
-
- if (reverse) args << QString("-x") << QString("reverse");
- if (simplify) args << QString("-x") << QString("simplify,count=%1").arg(limitTo);
-
- return args;
-}
-
-//------------------------------------------------------------------------
-QStringList MiscFltFilterData::makeOptionString()
-{
- QStringList args;
- if (!inUse)
- return args;
-
- if (nukeRoutes || nukeTracks || nukeWaypoints) {
- args << QString("-x");
- QString s = "nuketypes";
- if (nukeRoutes) s += ",routes";
- if (nukeTracks) s += ",tracks";
- if (nukeWaypoints) s += ",waypoints";
- args << s;
- }
-
- if (swap) args << "-x" << "swap";
-
- if (transform) {
- static const char *xformStr[] = {
- "wpt=trk",
- "trk=rte",
- "rte=wpt",
- "wpt=rte",
- "rte=trk",
- "trk=wpt",
- };
- args << QString("-x");
- QString s= QString("transform,%1").arg(xformStr[transformVal]);
- if (del) s += ",del";
- args << s;
- }
- return args;
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: filterdlg.cpp,v 1.4 2009-09-08 16:06:32 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+#include <QMessageBox>
+#include "filterdlg.h"
+#include "help.h"
+#include "appname.h"
+
+int FilterDialog::lastPage = 0;
+
+FilterDialog::FilterDialog(QWidget*parent, AllFiltersData &fd): QDialog(parent), fd(fd)
+{
+ ui.setupUi(this);
+ ui.filterList->clear();
+
+ widgetStack = new QStackedWidget(ui.frame);
+ QHBoxLayout *layout = new QHBoxLayout(ui.frame);
+ layout->addWidget(widgetStack);
+ layout->setContentsMargins(2, 2, 2, 2);
+
+ addFilterPage(tr("Tracks"),
+ new TrackWidget(widgetStack, fd.trackFilterData), &fd.trackFilterData.inUse);
+
+ addFilterPage(tr("Waypoints"),
+ new WayPtsWidget(widgetStack, fd.wayPtsFilterData), &fd.wayPtsFilterData.inUse);
+
+ addFilterPage(tr("Routes & Tracks"),
+ new RtTrkWidget(widgetStack, fd.rtTrkFilterData), &fd.rtTrkFilterData.inUse);
+
+ addFilterPage(tr("Miscellaneous"),
+ new MiscFltWidget(widgetStack, fd.miscFltFilterData), &fd.miscFltFilterData.inUse);
+
+ connect(ui.filterList, SIGNAL(currentRowChanged(int)),
+ this, SLOT(pageSelectionChanged(int)));
+
+ connect(ui.filterList, SIGNAL(itemClicked(QListWidgetItem *)),
+ this, SLOT(itemClickedX(QListWidgetItem*)));
+
+ connect(ui.helpButton, SIGNAL(clicked()), this, SLOT(helpX()));
+ connect(ui.resetButton, SIGNAL(clicked()), this, SLOT(resetX()));
+
+
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
+ ui.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
+
+ ui.filterList->setCurrentRow(lastPage);
+
+ // So that it occupies minimum space.
+ this->resize(100, 100);
+}
+
+
+//------------------------------------------------------------------------
+void FilterDialog::addFilterPage(const QString &name, FilterWidget *fw, bool*use)
+{
+ QListWidgetItem *it = new QListWidgetItem(name);
+ it->setCheckState(*use? Qt::Checked:Qt::Unchecked);
+ fw->setEnabled(*use);
+ ui.filterList->addItem(it);
+ widgetStack->addWidget(fw);
+ pages << fw;
+ usePages << use;
+}
+
+//------------------------------------------------------------------------
+void FilterDialog::itemClickedX(QListWidgetItem *it)
+{
+ int row = ui.filterList->row(it);
+ bool b = (it->checkState() == Qt::Checked);
+ pages[row]->setEnabled(b);
+ pages[row]->checkChecks();
+}
+//------------------------------------------------------------------------
+void FilterDialog::pageSelectionChanged(int i)
+{
+ widgetStack->setCurrentWidget(pages[i]);
+}
+
+//------------------------------------------------------------------------
+void FilterDialog::resetX()
+{
+ int ret = QMessageBox::warning
+ (this, QString(appName),
+ tr("Are you sure you want to reset all filter options to default values?"),
+ QMessageBox::Yes | QMessageBox::No);
+
+ if (ret == QMessageBox::Yes) {
+ fd.defaultAll();
+ for (int i=0; i<pages.size(); i++) {
+ pages[i]->setWidgetValues();
+ pages[i]->setEnabled(*(usePages[i]));
+ pages[i]->checkChecks();
+ ui.filterList->item(i)->setCheckState(*(usePages[i]) ? Qt::Checked: Qt::Unchecked);
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+void FilterDialog::helpX()
+{
+ ShowHelp("Data_Filters.html");
+}
+
+//------------------------------------------------------------------------
+void FilterDialog::runDialog()
+{
+ if (exec()) {
+ for (int i=0; i<pages.size(); i++) {
+ pages[i]->getWidgetValues();
+ *(usePages[i]) = ui.filterList->item(i)->checkState() == Qt::Checked;
+ }
+ }
+ lastPage = ui.filterList->currentRow();
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: filterdlg.cpp,v 1.4 2009-09-08 16:06:32 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-#include <QMessageBox>
-#include "filterdlg.h"
-#include "help.h"
-#include "appname.h"
-
-int FilterDialog::lastPage = 0;
-
-FilterDialog::FilterDialog(QWidget*parent, AllFiltersData &fd): QDialog(parent), fd(fd)
-{
- ui.setupUi(this);
- ui.filterList->clear();
-
- widgetStack = new QStackedWidget(ui.frame);
- QHBoxLayout *layout = new QHBoxLayout(ui.frame);
- layout->addWidget(widgetStack);
- layout->setContentsMargins(2, 2, 2, 2);
-
- addFilterPage(tr("Tracks"),
- new TrackWidget(widgetStack, fd.trackFilterData), &fd.trackFilterData.inUse);
-
- addFilterPage(tr("Waypoints"),
- new WayPtsWidget(widgetStack, fd.wayPtsFilterData), &fd.wayPtsFilterData.inUse);
-
- addFilterPage(tr("Routes & Tracks"),
- new RtTrkWidget(widgetStack, fd.rtTrkFilterData), &fd.rtTrkFilterData.inUse);
-
- addFilterPage(tr("Miscellaneous"),
- new MiscFltWidget(widgetStack, fd.miscFltFilterData), &fd.miscFltFilterData.inUse);
-
- connect(ui.filterList, SIGNAL(currentRowChanged(int)),
- this, SLOT(pageSelectionChanged(int)));
-
- connect(ui.filterList, SIGNAL(itemClicked(QListWidgetItem *)),
- this, SLOT(itemClickedX(QListWidgetItem*)));
-
- connect(ui.helpButton, SIGNAL(clicked()), this, SLOT(helpX()));
- connect(ui.resetButton, SIGNAL(clicked()), this, SLOT(resetX()));
-
-
- ui.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
- ui.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
-
- ui.filterList->setCurrentRow(lastPage);
-
- // So that it occupies minimum space.
- this->resize(100, 100);
-}
-
-
-//------------------------------------------------------------------------
-void FilterDialog::addFilterPage(const QString &name, FilterWidget *fw, bool*use)
-{
- QListWidgetItem *it = new QListWidgetItem(name);
- it->setCheckState(*use? Qt::Checked:Qt::Unchecked);
- fw->setEnabled(*use);
- ui.filterList->addItem(it);
- widgetStack->addWidget(fw);
- pages << fw;
- usePages << use;
-}
-
-//------------------------------------------------------------------------
-void FilterDialog::itemClickedX(QListWidgetItem *it)
-{
- int row = ui.filterList->row(it);
- bool b = (it->checkState() == Qt::Checked);
- pages[row]->setEnabled(b);
- pages[row]->checkChecks();
-}
-//------------------------------------------------------------------------
-void FilterDialog::pageSelectionChanged(int i)
-{
- widgetStack->setCurrentWidget(pages[i]);
-}
-
-//------------------------------------------------------------------------
-void FilterDialog::resetX()
-{
- int ret = QMessageBox::warning
- (this, QString(appName),
- tr("Are you sure you want to reset all filter options to default values?"),
- QMessageBox::Yes | QMessageBox::No);
-
- if (ret == QMessageBox::Yes) {
- fd.defaultAll();
- for (int i=0; i<pages.size(); i++) {
- pages[i]->setWidgetValues();
- pages[i]->setEnabled(*(usePages[i]));
- pages[i]->checkChecks();
- ui.filterList->item(i)->setCheckState(*(usePages[i]) ? Qt::Checked: Qt::Unchecked);
- }
- }
-}
-
-//------------------------------------------------------------------------
-void FilterDialog::helpX()
-{
- ShowHelp("Data_Filters.html");
-}
-
-//------------------------------------------------------------------------
-void FilterDialog::runDialog()
-{
- if (exec()) {
- for (int i=0; i<pages.size(); i++) {
- pages[i]->getWidgetValues();
- *(usePages[i]) = ui.filterList->item(i)->checkState() == Qt::Checked;
- }
- }
- lastPage = ui.filterList->currentRow();
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: filterwidgets.cpp,v 1.5 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+
+#include "filterwidgets.h"
+
+
+//------------------------------------------------------------------------
+TrackWidget::TrackWidget(QWidget *parent, TrackFilterData &tfd): FilterWidget(parent) , tfd(tfd)
+{
+ ui.setupUi(this);
+
+ // Checkbox interlocks
+ addCheckEnabler(ui.titleCheck, ui.titleText);
+ addCheckEnabler(ui.moveCheck,
+ (QList<QWidget *> ()
+ << ui.daysLabel << ui.daysSpin
+ << ui.hoursLabel<< ui.hoursSpin
+ << ui.minsLabel << ui.minsSpin
+ << ui.secsLabel << ui.secsSpin));
+ addCheckEnabler(ui.startCheck, ui.startEdit);
+ addCheckEnabler(ui.stopCheck, ui.stopEdit);
+ addCheckEnabler(ui.GPSFixesCheck, ui.GPSFixesCombo);
+
+ addCheckEnabler(ui.splitTimeCheck,
+ (QList<QWidget *> ()
+ <<ui.splitTimeSpin
+ <<ui.splitTimeCombo));
+ addCheckEnabler(ui.splitDistanceCheck,
+ (QList<QWidget *> ()
+ <<ui.splitDistSpin
+ <<ui.splitDistCombo));
+
+ connect(ui.mergeCheck, SIGNAL(clicked()) , this, SLOT(mergeCheckX()));
+ connect(ui.packCheck, SIGNAL(clicked()), this, SLOT(packCheckX()));
+ connect(ui.startCheck, SIGNAL(clicked()), this, SLOT(otherCheckX()));
+ connect(ui.stopCheck, SIGNAL(clicked()), this, SLOT(otherCheckX()));
+
+ connect(ui.splitDateCheck, SIGNAL(clicked()), this, SLOT(splitDateX()));
+ connect(ui.splitTimeCheck, SIGNAL(clicked()), this, SLOT(splitTimeX()));
+ connect(ui.splitDistanceCheck, SIGNAL(clicked()), this, SLOT(splitDistanceX()));
+
+ ui.startEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
+ ui.stopEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
+
+ // Collect the data fields.
+ fopts << new BoolFilterOption(tfd.title, ui.titleCheck);
+ fopts << new BoolFilterOption(tfd.move, ui.moveCheck);
+ fopts << new BoolFilterOption(tfd.TZ, ui.TZCheck);
+ fopts << new BoolFilterOption(tfd.start, ui.startCheck);
+ fopts << new BoolFilterOption(tfd.stop, ui.stopCheck);
+ fopts << new BoolFilterOption(tfd.pack, ui.packCheck);
+ fopts << new BoolFilterOption(tfd.merge, ui.mergeCheck);
+ fopts << new BoolFilterOption(tfd.splitByDate, ui.splitDateCheck);
+ fopts << new BoolFilterOption(tfd.splitByTime, ui.splitTimeCheck);
+ fopts << new BoolFilterOption(tfd.splitByDistance, ui.splitDistanceCheck);
+ fopts << new BoolFilterOption(tfd.GPSFixes, ui.GPSFixesCheck);
+ fopts << new BoolFilterOption(tfd.course, ui.courseCheck);
+ fopts << new BoolFilterOption(tfd.speed, ui.speedCheck);
+
+ fopts << new IntSpinFilterOption(tfd.days, ui.daysSpin, -2000, 2000);
+ fopts << new IntSpinFilterOption(tfd.hours, ui.hoursSpin);
+ fopts << new IntSpinFilterOption(tfd.mins, ui.minsSpin);
+ fopts << new IntSpinFilterOption(tfd.secs, ui.secsSpin);
+ fopts << new IntSpinFilterOption(tfd.splitTime, ui.splitTimeSpin, 0, 1000);
+ fopts << new IntSpinFilterOption(tfd.splitDist, ui.splitDistSpin, 0, 5280);
+
+ fopts << new DateTimeFilterOption(tfd.startTime, ui.startEdit);
+ fopts << new DateTimeFilterOption(tfd.stopTime, ui.stopEdit);
+
+ fopts << new StringFilterOption(tfd.titleString, ui.titleText);
+ fopts << new ComboFilterOption(tfd.GPSFixesVal, ui.GPSFixesCombo);
+ fopts << new ComboFilterOption(tfd.splitTimeUnit, ui.splitTimeCombo);
+ fopts << new ComboFilterOption(tfd.splitDistUnit, ui.splitDistCombo);
+ setWidgetValues();
+ checkChecks();
+}
+
+//------------------------------------------------------------------------
+void TrackWidget::otherCheckX()
+{
+ ui.TZCheck->setEnabled(ui.stopCheck->isChecked() || ui.startCheck->isChecked());
+
+ ui.splitTimeSpin->setEnabled(ui.splitTimeCheck->isChecked());
+ ui.splitTimeCombo->setEnabled(ui.splitTimeCheck->isChecked());
+ ui.splitDistSpin->setEnabled(ui.splitDistanceCheck->isChecked());
+ ui.splitDistCombo->setEnabled(ui.splitDistanceCheck->isChecked());
+
+ bool bb = (ui.mergeCheck->isChecked() || ui.packCheck->isChecked());
+ ui.splitDateCheck->setEnabled(bb);
+ ui.splitTimeCheck->setEnabled(bb);
+ ui.splitDistanceCheck->setEnabled(bb);
+}
+
+//------------------------------------------------------------------------
+void TrackWidget::mergeCheckX()
+{
+ if (ui.mergeCheck->isChecked())
+ ui.packCheck->setChecked(false);
+ otherCheckX();
+}
+//------------------------------------------------------------------------
+void TrackWidget::packCheckX()
+{
+ if (ui.packCheck->isChecked())
+ ui.mergeCheck->setChecked(false);
+ otherCheckX();
+}
+
+//------------------------------------------------------------------------
+void TrackWidget::splitDateX()
+{
+ if (ui.splitDateCheck->isChecked()) {
+ ui.splitTimeCheck->setChecked(false);
+ ui.splitDistanceCheck->setChecked(false);
+ }
+ otherCheckX();
+}
+//------------------------------------------------------------------------
+void TrackWidget::splitTimeX()
+{
+ if (ui.splitTimeCheck->isChecked()) {
+ ui.splitDateCheck->setChecked(false);
+ ui.splitDistanceCheck->setChecked(false);
+ }
+ otherCheckX();
+}
+//------------------------------------------------------------------------
+void TrackWidget::splitDistanceX()
+{
+ if (ui.splitDistanceCheck->isChecked()) {
+ ui.splitDateCheck->setChecked(false);
+ ui.splitTimeCheck->setChecked(false);
+ }
+ otherCheckX();
+}
+
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+WayPtsWidget::WayPtsWidget(QWidget *parent, WayPtsFilterData &wfd): FilterWidget(parent) , wfd(wfd)
+{
+ ui.setupUi(this);
+ addCheckEnabler(ui.duplicatesCheck,
+ QList<QWidget*>() << ui.shortNamesCheck << ui.locationsCheck);
+ addCheckEnabler(ui.positionCheck,
+ QList<QWidget*>() << ui.positionText << ui.positionUnitCombo);
+ addCheckEnabler(ui.radiusCheck,
+ QList<QWidget*>() << ui.latLabel << ui.latText << ui.longLabel <<
+ ui.longText << ui.radiusUnitCombo << ui.radiusText);
+
+ fopts << new BoolFilterOption(wfd.duplicates, ui.duplicatesCheck);
+ fopts << new BoolFilterOption(wfd.shortNames, ui.shortNamesCheck);
+ fopts << new BoolFilterOption(wfd.locations, ui.locationsCheck);
+ fopts << new BoolFilterOption(wfd.position, ui.positionCheck);
+ fopts << new BoolFilterOption(wfd.radius, ui.radiusCheck);
+ fopts << new BoolFilterOption(wfd.sort, ui.sortCheck);
+ fopts << new DoubleFilterOption(wfd.positionVal, ui.positionText, 0.0, 1.0E308);
+ fopts << new DoubleFilterOption(wfd.radiusVal, ui.radiusText, 0.0, 1.0E308);
+ fopts << new DoubleFilterOption(wfd.longVal, ui.longText, -180, 180, 7, 'f');
+ fopts << new DoubleFilterOption(wfd.latVal, ui.latText, -90, 90, 7, 'f');
+ fopts << new ComboFilterOption(wfd.positionUnit, ui.positionUnitCombo);
+ fopts << new ComboFilterOption(wfd.radiusUnit, ui.radiusUnitCombo);
+
+ connect(ui.shortNamesCheck, SIGNAL(clicked()), this, SLOT(shortNamesCkX()));
+ connect(ui.locationsCheck, SIGNAL(clicked()), this, SLOT(locationsCkX()));
+ setWidgetValues();
+ checkChecks();
+}
+//------------------------------------------------------------------------
+void WayPtsWidget::shortNamesCkX()
+{
+ if (!ui.shortNamesCheck->isChecked())
+ ui.locationsCheck->setChecked(true);
+}
+//------------------------------------------------------------------------
+void WayPtsWidget::locationsCkX()
+{
+ if (!ui.locationsCheck->isChecked())
+ ui.shortNamesCheck->setChecked(true);
+}
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+RtTrkWidget::RtTrkWidget(QWidget *parent, RtTrkFilterData &rfd): FilterWidget(parent) , rfd(rfd)
+{
+ ui.setupUi(this);
+ addCheckEnabler(ui.simplifyCheck,
+ QList<QWidget*>() << ui.limitToLabel << ui.limitToSpin << ui.pointLabel);
+
+ fopts << new BoolFilterOption(rfd.simplify, ui.simplifyCheck);
+ fopts << new BoolFilterOption(rfd.reverse, ui.reverseCheck);
+ fopts << new IntSpinFilterOption(rfd.limitTo, ui.limitToSpin, 1, 5000);
+ setWidgetValues();
+ checkChecks();
+}
+
+//------------------------------------------------------------------------
+//------------------------------------------------------------------------
+MiscFltWidget::MiscFltWidget(QWidget *parent, MiscFltFilterData &mfd): FilterWidget(parent) , mfd(mfd)
+{
+ ui.setupUi(this);
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Tracks")).arg(QChar(8594)).arg(tr("Waypoints")));
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Routes")).arg(QChar(8594)).arg(tr("Tracks")));
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Waypoints")).arg(QChar(8594)).arg(tr("Routes")));
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Routes")).arg(QChar(8594)).arg(tr("Waypoints")));
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Tracks")).arg(QChar(8594)).arg(tr("Routes")));
+ ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Waypoints")).arg(QChar(8594)).arg(tr("Tracks")));
+ addCheckEnabler(ui.transformCheck,
+ QList<QWidget*>() << ui.transformCombo << ui.deleteCheck);
+
+ fopts << new BoolFilterOption(mfd.transform, ui.transformCheck);
+ fopts << new BoolFilterOption(mfd.swap, ui.swapCheck);
+ fopts << new BoolFilterOption(mfd.del, ui.deleteCheck);
+ fopts << new BoolFilterOption(mfd.nukeTracks, ui.nukeTracks);
+ fopts << new BoolFilterOption(mfd.nukeRoutes, ui.nukeRoutes);
+ fopts << new BoolFilterOption(mfd.nukeWaypoints, ui.nukeWaypoints);
+ fopts << new ComboFilterOption(mfd.transformVal, ui.transformCombo);
+
+ setWidgetValues();
+ checkChecks();
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: filterwidgets.cpp,v 1.5 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-
-#include "filterwidgets.h"
-
-
-//------------------------------------------------------------------------
-TrackWidget::TrackWidget(QWidget *parent, TrackFilterData &tfd): FilterWidget(parent) , tfd(tfd)
-{
- ui.setupUi(this);
-
- // Checkbox interlocks
- addCheckEnabler(ui.titleCheck, ui.titleText);
- addCheckEnabler(ui.moveCheck,
- (QList<QWidget *> ()
- << ui.daysLabel << ui.daysSpin
- << ui.hoursLabel<< ui.hoursSpin
- << ui.minsLabel << ui.minsSpin
- << ui.secsLabel << ui.secsSpin));
- addCheckEnabler(ui.startCheck, ui.startEdit);
- addCheckEnabler(ui.stopCheck, ui.stopEdit);
- addCheckEnabler(ui.GPSFixesCheck, ui.GPSFixesCombo);
-
- addCheckEnabler(ui.splitTimeCheck,
- (QList<QWidget *> ()
- <<ui.splitTimeSpin
- <<ui.splitTimeCombo));
- addCheckEnabler(ui.splitDistanceCheck,
- (QList<QWidget *> ()
- <<ui.splitDistSpin
- <<ui.splitDistCombo));
-
- connect(ui.mergeCheck, SIGNAL(clicked()) , this, SLOT(mergeCheckX()));
- connect(ui.packCheck, SIGNAL(clicked()), this, SLOT(packCheckX()));
- connect(ui.startCheck, SIGNAL(clicked()), this, SLOT(otherCheckX()));
- connect(ui.stopCheck, SIGNAL(clicked()), this, SLOT(otherCheckX()));
-
- connect(ui.splitDateCheck, SIGNAL(clicked()), this, SLOT(splitDateX()));
- connect(ui.splitTimeCheck, SIGNAL(clicked()), this, SLOT(splitTimeX()));
- connect(ui.splitDistanceCheck, SIGNAL(clicked()), this, SLOT(splitDistanceX()));
-
- ui.startEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
- ui.stopEdit->setDisplayFormat("dd MMM yyyy hh:mm:ss AP");
-
- // Collect the data fields.
- fopts << new BoolFilterOption(tfd.title, ui.titleCheck);
- fopts << new BoolFilterOption(tfd.move, ui.moveCheck);
- fopts << new BoolFilterOption(tfd.TZ, ui.TZCheck);
- fopts << new BoolFilterOption(tfd.start, ui.startCheck);
- fopts << new BoolFilterOption(tfd.stop, ui.stopCheck);
- fopts << new BoolFilterOption(tfd.pack, ui.packCheck);
- fopts << new BoolFilterOption(tfd.merge, ui.mergeCheck);
- fopts << new BoolFilterOption(tfd.splitByDate, ui.splitDateCheck);
- fopts << new BoolFilterOption(tfd.splitByTime, ui.splitTimeCheck);
- fopts << new BoolFilterOption(tfd.splitByDistance, ui.splitDistanceCheck);
- fopts << new BoolFilterOption(tfd.GPSFixes, ui.GPSFixesCheck);
- fopts << new BoolFilterOption(tfd.course, ui.courseCheck);
- fopts << new BoolFilterOption(tfd.speed, ui.speedCheck);
-
- fopts << new IntSpinFilterOption(tfd.days, ui.daysSpin, -2000, 2000);
- fopts << new IntSpinFilterOption(tfd.hours, ui.hoursSpin);
- fopts << new IntSpinFilterOption(tfd.mins, ui.minsSpin);
- fopts << new IntSpinFilterOption(tfd.secs, ui.secsSpin);
- fopts << new IntSpinFilterOption(tfd.splitTime, ui.splitTimeSpin, 0, 1000);
- fopts << new IntSpinFilterOption(tfd.splitDist, ui.splitDistSpin, 0, 5280);
-
- fopts << new DateTimeFilterOption(tfd.startTime, ui.startEdit);
- fopts << new DateTimeFilterOption(tfd.stopTime, ui.stopEdit);
-
- fopts << new StringFilterOption(tfd.titleString, ui.titleText);
- fopts << new ComboFilterOption(tfd.GPSFixesVal, ui.GPSFixesCombo);
- fopts << new ComboFilterOption(tfd.splitTimeUnit, ui.splitTimeCombo);
- fopts << new ComboFilterOption(tfd.splitDistUnit, ui.splitDistCombo);
- setWidgetValues();
- checkChecks();
-}
-
-//------------------------------------------------------------------------
-void TrackWidget::otherCheckX()
-{
- ui.TZCheck->setEnabled(ui.stopCheck->isChecked() || ui.startCheck->isChecked());
-
- ui.splitTimeSpin->setEnabled(ui.splitTimeCheck->isChecked());
- ui.splitTimeCombo->setEnabled(ui.splitTimeCheck->isChecked());
- ui.splitDistSpin->setEnabled(ui.splitDistanceCheck->isChecked());
- ui.splitDistCombo->setEnabled(ui.splitDistanceCheck->isChecked());
-
- bool bb = (ui.mergeCheck->isChecked() || ui.packCheck->isChecked());
- ui.splitDateCheck->setEnabled(bb);
- ui.splitTimeCheck->setEnabled(bb);
- ui.splitDistanceCheck->setEnabled(bb);
-}
-
-//------------------------------------------------------------------------
-void TrackWidget::mergeCheckX()
-{
- if (ui.mergeCheck->isChecked())
- ui.packCheck->setChecked(false);
- otherCheckX();
-}
-//------------------------------------------------------------------------
-void TrackWidget::packCheckX()
-{
- if (ui.packCheck->isChecked())
- ui.mergeCheck->setChecked(false);
- otherCheckX();
-}
-
-//------------------------------------------------------------------------
-void TrackWidget::splitDateX()
-{
- if (ui.splitDateCheck->isChecked()) {
- ui.splitTimeCheck->setChecked(false);
- ui.splitDistanceCheck->setChecked(false);
- }
- otherCheckX();
-}
-//------------------------------------------------------------------------
-void TrackWidget::splitTimeX()
-{
- if (ui.splitTimeCheck->isChecked()) {
- ui.splitDateCheck->setChecked(false);
- ui.splitDistanceCheck->setChecked(false);
- }
- otherCheckX();
-}
-//------------------------------------------------------------------------
-void TrackWidget::splitDistanceX()
-{
- if (ui.splitDistanceCheck->isChecked()) {
- ui.splitDateCheck->setChecked(false);
- ui.splitTimeCheck->setChecked(false);
- }
- otherCheckX();
-}
-
-
-//------------------------------------------------------------------------
-//------------------------------------------------------------------------
-WayPtsWidget::WayPtsWidget(QWidget *parent, WayPtsFilterData &wfd): FilterWidget(parent) , wfd(wfd)
-{
- ui.setupUi(this);
- addCheckEnabler(ui.duplicatesCheck,
- QList<QWidget*>() << ui.shortNamesCheck << ui.locationsCheck);
- addCheckEnabler(ui.positionCheck,
- QList<QWidget*>() << ui.positionText << ui.positionUnitCombo);
- addCheckEnabler(ui.radiusCheck,
- QList<QWidget*>() << ui.latLabel << ui.latText << ui.longLabel <<
- ui.longText << ui.radiusUnitCombo << ui.radiusText);
-
- fopts << new BoolFilterOption(wfd.duplicates, ui.duplicatesCheck);
- fopts << new BoolFilterOption(wfd.shortNames, ui.shortNamesCheck);
- fopts << new BoolFilterOption(wfd.locations, ui.locationsCheck);
- fopts << new BoolFilterOption(wfd.position, ui.positionCheck);
- fopts << new BoolFilterOption(wfd.radius, ui.radiusCheck);
- fopts << new BoolFilterOption(wfd.sort, ui.sortCheck);
- fopts << new DoubleFilterOption(wfd.positionVal, ui.positionText, 0.0, 1.0E308);
- fopts << new DoubleFilterOption(wfd.radiusVal, ui.radiusText, 0.0, 1.0E308);
- fopts << new DoubleFilterOption(wfd.longVal, ui.longText, -180, 180, 7, 'f');
- fopts << new DoubleFilterOption(wfd.latVal, ui.latText, -90, 90, 7, 'f');
- fopts << new ComboFilterOption(wfd.positionUnit, ui.positionUnitCombo);
- fopts << new ComboFilterOption(wfd.radiusUnit, ui.radiusUnitCombo);
-
- connect(ui.shortNamesCheck, SIGNAL(clicked()), this, SLOT(shortNamesCkX()));
- connect(ui.locationsCheck, SIGNAL(clicked()), this, SLOT(locationsCkX()));
- setWidgetValues();
- checkChecks();
-}
-//------------------------------------------------------------------------
-void WayPtsWidget::shortNamesCkX()
-{
- if (!ui.shortNamesCheck->isChecked())
- ui.locationsCheck->setChecked(true);
-}
-//------------------------------------------------------------------------
-void WayPtsWidget::locationsCkX()
-{
- if (!ui.locationsCheck->isChecked())
- ui.shortNamesCheck->setChecked(true);
-}
-
-//------------------------------------------------------------------------
-//------------------------------------------------------------------------
-RtTrkWidget::RtTrkWidget(QWidget *parent, RtTrkFilterData &rfd): FilterWidget(parent) , rfd(rfd)
-{
- ui.setupUi(this);
- addCheckEnabler(ui.simplifyCheck,
- QList<QWidget*>() << ui.limitToLabel << ui.limitToSpin << ui.pointLabel);
-
- fopts << new BoolFilterOption(rfd.simplify, ui.simplifyCheck);
- fopts << new BoolFilterOption(rfd.reverse, ui.reverseCheck);
- fopts << new IntSpinFilterOption(rfd.limitTo, ui.limitToSpin, 1, 5000);
- setWidgetValues();
- checkChecks();
-}
-
-//------------------------------------------------------------------------
-//------------------------------------------------------------------------
-MiscFltWidget::MiscFltWidget(QWidget *parent, MiscFltFilterData &mfd): FilterWidget(parent) , mfd(mfd)
-{
- ui.setupUi(this);
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Tracks")).arg(QChar(8594)).arg(tr("Waypoints")));
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Routes")).arg(QChar(8594)).arg(tr("Tracks")));
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Waypoints")).arg(QChar(8594)).arg(tr("Routes")));
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Routes")).arg(QChar(8594)).arg(tr("Waypoints")));
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Tracks")).arg(QChar(8594)).arg(tr("Routes")));
- ui.transformCombo->addItem(QString("%1 %2 %3").arg(tr("Waypoints")).arg(QChar(8594)).arg(tr("Tracks")));
- addCheckEnabler(ui.transformCheck,
- QList<QWidget*>() << ui.transformCombo << ui.deleteCheck);
-
- fopts << new BoolFilterOption(mfd.transform, ui.transformCheck);
- fopts << new BoolFilterOption(mfd.swap, ui.swapCheck);
- fopts << new BoolFilterOption(mfd.del, ui.deleteCheck);
- fopts << new BoolFilterOption(mfd.nukeTracks, ui.nukeTracks);
- fopts << new BoolFilterOption(mfd.nukeRoutes, ui.nukeRoutes);
- fopts << new BoolFilterOption(mfd.nukeWaypoints, ui.nukeWaypoints);
- fopts << new ComboFilterOption(mfd.transformVal, ui.transformCombo);
-
- setWidgetValues();
- checkChecks();
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: format.cpp,v 1.4 2010-02-14 05:33:37 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include "format.h"
+#include "mainwindow.h"
+
+QString Format::htmlBase = QString();
+
+static void saveOptions(QSettings &settings, const QString &prefix, const QList<FormatOption> &options) {
+ for (int i=0; i<options.size(); i++) {
+ QString kp = prefix + "." + options[i].getName();
+ QString k1 = kp + ".selected";
+ QString k2 = kp + ".value";
+ settings.setValue(k1, options[i].getSelected());
+ settings.setValue(k2, options[i].getValue());
+ }
+}
+
+static void restoreOptions(QSettings &settings, const QString&prefix, QList<FormatOption> &options) {
+ for (int i=0; i<options.size(); i++) {
+ QString kp = prefix + "." + options[i].getName();
+ QString k1 = kp + ".selected";
+ QString k2 = kp + ".value";
+ if (settings.contains(k1) && settings.contains(k2)) {
+ options[i].setSelected(settings.value(k1).toBool());
+ options[i].setValue(settings.value(k2));
+ }
+ }
+}
+
+void Format::saveSettings(QSettings &settings)
+{
+ saveOptions(settings, name+".input", inputOptions);
+ saveOptions(settings, name+".output", outputOptions);
+ settings.setValue(name + ".readcount", getReadUseCount());
+ settings.setValue(name + ".writecount", getWriteUseCount());
+ settings.setValue(name+".hidden", isHidden());
+}
+
+void Format::restoreSettings(QSettings &settings)
+{
+ restoreOptions(settings, name + ".input", inputOptions);
+ restoreOptions(settings, name + ".output", outputOptions);
+ bumpReadUseCount(settings.value(name + ".readcount").toInt());
+ bumpWriteUseCount(settings.value(name + ".writecount").toInt());
+ hidden_ = settings.value(name + ".hidden", false).toBool();
+}
+
+void Format::setToDefault()
+{
+ for (int i=0; i<inputOptions.size(); i++) {
+ inputOptions[i].setSelected(false);
+ inputOptions[i].setValue(QVariant());
+ }
+ for (int i=0; i<outputOptions.size(); i++) {
+ outputOptions[i].setSelected(false);
+ outputOptions[i].setValue(QVariant());
+ }
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: format.cpp,v 1.4 2010-02-14 05:33:37 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include "format.h"
-#include "mainwindow.h"
-
-QString Format::htmlBase = QString();
-
-static void saveOptions(QSettings &settings, const QString &prefix, const QList<FormatOption> &options) {
- for (int i=0; i<options.size(); i++) {
- QString kp = prefix + "." + options[i].getName();
- QString k1 = kp + ".selected";
- QString k2 = kp + ".value";
- settings.setValue(k1, options[i].getSelected());
- settings.setValue(k2, options[i].getValue());
- }
-}
-
-static void restoreOptions(QSettings &settings, const QString&prefix, QList<FormatOption> &options) {
- for (int i=0; i<options.size(); i++) {
- QString kp = prefix + "." + options[i].getName();
- QString k1 = kp + ".selected";
- QString k2 = kp + ".value";
- if (settings.contains(k1) && settings.contains(k2)) {
- options[i].setSelected(settings.value(k1).toBool());
- options[i].setValue(settings.value(k2));
- }
- }
-}
-
-void Format::saveSettings(QSettings &settings)
-{
- saveOptions(settings, name+".input", inputOptions);
- saveOptions(settings, name+".output", outputOptions);
- settings.setValue(name + ".readcount", getReadUseCount());
- settings.setValue(name + ".writecount", getWriteUseCount());
- settings.setValue(name+".hidden", isHidden());
-}
-
-void Format::restoreSettings(QSettings &settings)
-{
- restoreOptions(settings, name + ".input", inputOptions);
- restoreOptions(settings, name + ".output", outputOptions);
- bumpReadUseCount(settings.value(name + ".readcount").toInt());
- bumpWriteUseCount(settings.value(name + ".writecount").toInt());
- hidden_ = settings.value(name + ".hidden", false).toBool();
-}
-
-void Format::setToDefault()
-{
- for (int i=0; i<inputOptions.size(); i++) {
- inputOptions[i].setSelected(false);
- inputOptions[i].setValue(QVariant());
- }
- for (int i=0; i<outputOptions.size(); i++) {
- outputOptions[i].setSelected(false);
- outputOptions[i].setValue(QVariant());
- }
-}
--- /dev/null
+// -*- c++ -*-
+// $Id: formatload.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+#include <QProcess>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QCoreApplication>
+#include <QApplication>
+#include "formatload.h"
+#include "appname.h"
+
+//------------------------------------------------------------------------
+static QString xlt(const QString &f) {
+ return QCoreApplication::translate("", f.toStdString().c_str());
+}
+
+//------------------------------------------------------------------------
+bool FormatLoad::skipToValidLine()
+{
+ QRegExp regex("^(file|serial)");
+ while (currentLine <lines.size() && regex.indexIn(lines[currentLine]) != 0)
+ currentLine++;
+ return (currentLine<lines.size());
+}
+
+//------------------------------------------------------------------------
+bool FormatLoad::processFormat(Format &format)
+{
+ QStringList hfields = lines[currentLine++].split("\t");
+ if (hfields.size() < 5) {
+ return false;
+ }
+ QString htmlPage = lines[currentLine++];
+ htmlPage.replace(QRegExp("^[\\s]*"), "");
+ htmlPage.replace(QRegExp("[\\s]$"), "");
+
+ QRegExp regex("^option");
+ QList <FormatOption> optionList;
+ while (currentLine <lines.size() && regex.indexIn(lines[currentLine]) == 0) {
+ QStringList ofields = lines[currentLine].split("\t");
+ if (ofields.size() < 9) {
+ return false;
+ }
+ QString name = ofields[2];
+ QString description = ofields[3];
+ QString optionType = ofields[4];
+ QString optionDef = ofields[5];
+ QString optionMin = ofields[6];
+ QString optionMax = ofields[7];
+ QString optionHtml = ofields[8];
+ FormatOption::optionType type = FormatOption::OPTbool;
+ if (optionType == "boolean")
+ type = FormatOption::OPTbool;
+ else if (optionType == "string")
+ type = FormatOption::OPTstring;
+ else if (optionType == "integer") {
+ type = (optionMax != "" && optionMin != "") ? FormatOption::OPTboundedInt : FormatOption::OPTint;
+ if (optionMax == "")
+ optionMax = "2147483647";
+ if (optionMin == "")
+ optionMin = "-2147483647";
+ }
+ else if (optionType == "float") {
+ type = FormatOption::OPTfloat;
+ if (optionMax == "")
+ optionMax = "1.0E308";
+ if (optionMin == "")
+ optionMin = "-1.0E308";
+ }
+ else if (optionType == "file") {
+ type = FormatOption::OPTinFile;
+ }
+ else if (optionType == "outfile") {
+ type = FormatOption::OPToutFile;
+ }
+ else {
+ type = FormatOption::OPTstring;
+ }
+ optionList << FormatOption(name, xlt(description),
+ type, QVariant(optionDef), QVariant(optionMin),
+ QVariant(optionMax), optionHtml);
+ currentLine++;
+ }
+ QList <FormatOption> optionList2 = optionList;
+
+ format = Format(hfields[2], xlt(hfields[4]),
+ hfields[1][0] == QChar('r'), hfields[1][2] == QChar('r'), hfields[1][4] == QChar('r'),
+ hfields[1][1] == QChar('w'), hfields[1][3] == QChar('w'), hfields[1][5] == QChar('w'),
+ hfields[0] == "file",
+ hfields[0] == "serial",
+ QStringList() << hfields[3],
+ optionList,
+ optionList2, htmlPage);
+ if (htmlPage.length() > 0 && Format::getHtmlBase().length() == 0) {
+ QString base = htmlPage;
+ base.replace(QRegExp("/[^/]+$"), "/");
+ Format::setHtmlBase(base);
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------
+bool FormatLoad::getFormats(QList<Format> &formatList)
+{
+ formatList.clear();
+
+ QProcess babel;
+ babel.start("gpsbabel", QStringList() << "-^3");
+ if (!babel.waitForStarted())
+ return false;
+ babel.closeWriteChannel();
+ if (!babel.waitForFinished())
+ return false;
+ if (babel.exitCode() != 0)
+ return false;
+
+ QTextStream tstream(babel.readAll());
+ QList<int>lineList;
+ int k=0;
+ while(!tstream.atEnd()) {
+ QString l = tstream.readLine();
+ k++;
+ if (!QRegExp("^[\\s]*$").exactMatch(l)) {
+ lines << l;
+ lineList<<k;
+ }
+ }
+ currentLine = 0;
+
+ for (bool dataPresent = skipToValidLine(); dataPresent; dataPresent=skipToValidLine()) {
+ Format format;
+ if (!processFormat(format)) {
+ QMessageBox::information
+ (0, appName,
+ QObject::tr("Error processing formats from running process \"gpsbabel -^3\" at line %1").arg(lineList[currentLine]));
+ }
+ else {
+ formatList << format;
+ }
+ }
+ return true;
+}
+++ /dev/null
-// -*- c++ -*-
-// $Id: formatload.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-#include <QProcess>
-#include <QMessageBox>
-#include <QTextStream>
-#include <QCoreApplication>
-#include <QApplication>
-#include "formatload.h"
-#include "appname.h"
-
-//------------------------------------------------------------------------
-static QString xlt(const QString &f) {
- return QCoreApplication::translate("", f.toStdString().c_str());
-}
-
-//------------------------------------------------------------------------
-bool FormatLoad::skipToValidLine()
-{
- QRegExp regex("^(file|serial)");
- while (currentLine <lines.size() && regex.indexIn(lines[currentLine]) != 0)
- currentLine++;
- return (currentLine<lines.size());
-}
-
-//------------------------------------------------------------------------
-bool FormatLoad::processFormat(Format &format)
-{
- QStringList hfields = lines[currentLine++].split("\t");
- if (hfields.size() < 5) {
- return false;
- }
- QString htmlPage = lines[currentLine++];
- htmlPage.replace(QRegExp("^[\\s]*"), "");
- htmlPage.replace(QRegExp("[\\s]$"), "");
-
- QRegExp regex("^option");
- QList <FormatOption> optionList;
- while (currentLine <lines.size() && regex.indexIn(lines[currentLine]) == 0) {
- QStringList ofields = lines[currentLine].split("\t");
- if (ofields.size() < 9) {
- return false;
- }
- QString name = ofields[2];
- QString description = ofields[3];
- QString optionType = ofields[4];
- QString optionDef = ofields[5];
- QString optionMin = ofields[6];
- QString optionMax = ofields[7];
- QString optionHtml = ofields[8];
- FormatOption::optionType type = FormatOption::OPTbool;
- if (optionType == "boolean")
- type = FormatOption::OPTbool;
- else if (optionType == "string")
- type = FormatOption::OPTstring;
- else if (optionType == "integer") {
- type = (optionMax != "" && optionMin != "") ? FormatOption::OPTboundedInt : FormatOption::OPTint;
- if (optionMax == "")
- optionMax = "2147483647";
- if (optionMin == "")
- optionMin = "-2147483647";
- }
- else if (optionType == "float") {
- type = FormatOption::OPTfloat;
- if (optionMax == "")
- optionMax = "1.0E308";
- if (optionMin == "")
- optionMin = "-1.0E308";
- }
- else if (optionType == "file") {
- type = FormatOption::OPTinFile;
- }
- else if (optionType == "outfile") {
- type = FormatOption::OPToutFile;
- }
- else {
- type = FormatOption::OPTstring;
- }
- optionList << FormatOption(name, xlt(description),
- type, QVariant(optionDef), QVariant(optionMin),
- QVariant(optionMax), optionHtml);
- currentLine++;
- }
- QList <FormatOption> optionList2 = optionList;
-
- format = Format(hfields[2], xlt(hfields[4]),
- hfields[1][0] == QChar('r'), hfields[1][2] == QChar('r'), hfields[1][4] == QChar('r'),
- hfields[1][1] == QChar('w'), hfields[1][3] == QChar('w'), hfields[1][5] == QChar('w'),
- hfields[0] == "file",
- hfields[0] == "serial",
- QStringList() << hfields[3],
- optionList,
- optionList2, htmlPage);
- if (htmlPage.length() > 0 && Format::getHtmlBase().length() == 0) {
- QString base = htmlPage;
- base.replace(QRegExp("/[^/]+$"), "/");
- Format::setHtmlBase(base);
- }
- return true;
-}
-
-//------------------------------------------------------------------------
-bool FormatLoad::getFormats(QList<Format> &formatList)
-{
- formatList.clear();
-
- QProcess babel;
- babel.start("gpsbabel", QStringList() << "-^3");
- if (!babel.waitForStarted())
- return false;
- babel.closeWriteChannel();
- if (!babel.waitForFinished())
- return false;
- if (babel.exitCode() != 0)
- return false;
-
- QTextStream tstream(babel.readAll());
- QList<int>lineList;
- int k=0;
- while(!tstream.atEnd()) {
- QString l = tstream.readLine();
- k++;
- if (!QRegExp("^[\\s]*$").exactMatch(l)) {
- lines << l;
- lineList<<k;
- }
- }
- currentLine = 0;
-
- for (bool dataPresent = skipToValidLine(); dataPresent; dataPresent=skipToValidLine()) {
- Format format;
- if (!processFormat(format)) {
- QMessageBox::information
- (0, appName,
- QObject::tr("Error processing formats from running process \"gpsbabel -^3\" at line %1").arg(lineList[currentLine]));
- }
- else {
- formatList << format;
- }
- }
- return true;
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: gmapdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+#include <QStandardItemModel>
+#include <QMenu>
+#include <QHeaderView>
+#include "gmapdlg.h"
+#include "appname.h"
+#include "gpx.h"
+
+//------------------------------------------------------------------------
+class StandardItem: public QStandardItem
+{
+ public:
+ StandardItem(const QString &text): QStandardItem(text)
+ {
+ this->setEditable(false);
+ }
+};
+
+//------------------------------------------------------------------------
+class TreeAction: public QAction
+{
+public:
+ TreeAction(const QString &text,
+ QObject *obj, const char *member, QObject *parent): QAction(text, parent)
+ {
+ connect(this, SIGNAL(triggered()), obj, member);
+ }
+};
+//------------------------------------------------------------------------
+QString GMapDialog::formatLength(double l)
+{
+ double metricLength = l;
+ QString metricUnit = tr("meters");
+ int metricPrecision = 2;
+ if (l > 1000.0) {
+ metricLength = l/1000.0;
+ metricUnit = "km";
+ metricPrecision = 3;
+ }
+
+ double fpsLength = l*1000.0/25.4/12.0;
+ QString fpsUnit = tr("feet");
+ int fpsPrecision = 1;
+ if (fpsLength >5280.0) {
+ fpsLength /= 5280.0;
+ fpsUnit = tr("miles");
+ fpsPrecision = 3;
+ }
+ return QString(tr("Length: %1 %2\n %3 %4")
+ .arg(metricLength, 0, 'f', metricPrecision)
+ .arg(metricUnit)
+ .arg(fpsLength, 0, 'f', fpsPrecision)
+ .arg(fpsUnit));
+
+}
+//------------------------------------------------------------------------
+void GMapDialog::appendWaypointInfo(QStandardItem *it, const GpxWaypoint &wpt)
+{
+ it->appendRow(new StandardItem(tr("Lat: %1").arg(wpt.getLocation().lat(), 0, 'f', 7)));
+ it->appendRow(new StandardItem(tr("Lng: %1").arg(wpt.getLocation().lng(), 0, 'f', 7)));
+ if (wpt.getDescription() != QString())
+ it->appendRow(new StandardItem(tr("Desc: %1").arg(wpt.getDescription())));
+ if (wpt.getComment() != QString() && wpt.getComment() != wpt.getDescription())
+ it->appendRow(new StandardItem(tr("Cmt: %1").arg(wpt.getComment())));
+ if (wpt.getElevation() > -50000)
+ it->appendRow(new StandardItem(tr("Ele: %1").arg(wpt.getElevation())));
+
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::appendTrackInfo(QStandardItem *it, const GpxTrack &trk)
+{
+ QDateTime startTime, stopTime;
+ bool first = true;
+ int count = 0;
+ foreach (const GpxTrackSegment &seg, trk.getTrackSegments()) {
+ foreach (const GpxTrackPoint &pt, seg.getTrackPoints()) {
+ count++;
+ QDateTime t = pt.getDateTime();
+ if (!t.isValid())
+ continue;
+ if (first) {
+ startTime = t;
+ stopTime = t;
+ first = false;
+ }
+ else {
+ if (t < startTime)
+ startTime = t;
+ if (t > stopTime)
+ stopTime = t;
+ }
+ }
+ }
+ if (startTime.isValid()) {
+ it->appendRow(new StandardItem(tr("Start: %1")
+ .arg(startTime.toString("yyyy-MMM-dd HH:mm:ss"))));
+ it->appendRow(new StandardItem(tr("Stop: %1")
+ .arg(stopTime.toString("yyyy-MMM-dd HH:mm:ss"))));
+ }
+ it->appendRow(new StandardItem(tr("Points: %1").arg(count)));
+
+ it->appendRow(new StandardItem(formatLength(trk.length())));
+
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::appendRouteInfo(QStandardItem *it, const GpxRoute &rte)
+{
+ it->appendRow(new StandardItem(formatLength(rte.length())));
+}
+
+//------------------------------------------------------------------------
+GMapDialog::GMapDialog(QWidget *parent, const QString &gpxFileName, QPlainTextEdit *te): QDialog(parent)
+{
+ ui.setupUi(this);
+ this->setWindowTitle(QString(appName) + " " + QString("Google Maps"));
+ gpx.read(gpxFileName);
+
+ mapWidget = new Map(this, gpx, te);
+ QHBoxLayout *lay = new QHBoxLayout(ui.frame);
+ lay->setContentsMargins(0, 0, 0, 0);
+ lay->addWidget(mapWidget);
+
+ model = new QStandardItemModel(this);
+
+ wptItem = new StandardItem(tr("Waypoints"));
+ wptItem->setCheckable(true);
+ wptItem->setCheckState(Qt::Checked);
+ model->appendRow(wptItem);
+ for (int i=0; i<gpx.getWaypoints().size(); i++) {
+ GpxWaypoint &wpt = gpx.getWaypoints()[i];
+ QStandardItem *it = new StandardItem(wpt.getName());
+ wptItem->appendRow(it);
+ it->setCheckable(true);
+ it->setCheckState(Qt::Checked);
+ it->setData(qVariantFromValue((void *)&wpt));
+ appendWaypointInfo(it, wpt);
+ wptList << it;
+ }
+
+ trkItem = new StandardItem(tr("Tracks"));
+ trkItem->setCheckable(true);
+ trkItem->setCheckState(Qt::Checked);
+ model->appendRow(trkItem);
+ for (int i=0; i<gpx.getTracks().size(); i++) {
+ GpxTrack &trk = gpx.getTracks()[i];
+ QStandardItem *it = new StandardItem(trk.getName());
+ trkItem->appendRow(it);
+ it->setCheckable(true);
+ it->setCheckState(Qt::Checked);
+ it->setData(qVariantFromValue((void *)&trk));
+ appendTrackInfo(it, trk);
+ trkList << it;
+ }
+
+ rteItem = new StandardItem(tr("Routes"));
+ rteItem->setCheckable(true);
+ rteItem->setCheckState(Qt::Checked);
+ model->appendRow(rteItem);
+ for (int i=0; i<gpx.getRoutes().size(); i++) {
+ GpxRoute &rte = gpx.getRoutes()[i];
+ QStandardItem *it = new StandardItem(rte.getName());
+ rteItem->appendRow(it);
+ it->setCheckable(true);
+ it->setCheckState(Qt::Checked);
+ it->setData(qVariantFromValue((void *)&rte));
+ appendRouteInfo(it, rte);
+ rteList << it;
+ }
+
+ ui.treeView->header()->hide();
+ ui.treeView->setModel(model);
+ ui.treeView->setExpandsOnDoubleClick(false);
+ connect(model, SIGNAL(itemChanged(QStandardItem *)),
+ this, SLOT(itemChangedX(QStandardItem *)));
+ connect(mapWidget, SIGNAL(waypointClicked(int)), this, SLOT(waypointClickedX(int)));
+ connect(mapWidget, SIGNAL(routeClicked(int)), this, SLOT(routeClickedX(int)));
+ connect(mapWidget, SIGNAL(trackClicked(int)), this, SLOT(trackClickedX(int)));
+ connect(ui.treeView, SIGNAL(doubleClicked(const QModelIndex &)),
+ this, SLOT(treeDoubleClicked(const QModelIndex&)));
+ connect(ui.treeView->selectionModel(), SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
+ this, SLOT(selectionChangedX(const QItemSelection &, const QItemSelection &)));
+
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(const QPoint &)),
+ this, SLOT(showContextMenu(const QPoint &)));
+
+ connect(ui.copyButton, SIGNAL(clicked()), this, SLOT(copyButtonClickedX()));
+
+ ui.copyButton->hide(); // Hide for now, not working
+
+}
+
+//-------------------------------------------------------------------------
+void GMapDialog::itemChangedX(QStandardItem *it)
+{
+ bool show = (it->checkState() == Qt::Checked);
+ if (it == trkItem) {
+ if (show)
+ mapWidget->showTracks(gpx.getTracks());
+ else
+ mapWidget->hideAllTracks();
+ }
+
+ else if (it == wptItem) {
+ if (show)
+ mapWidget->showWaypoints(gpx.getWaypoints());
+ else
+ mapWidget->hideAllWaypoints();
+ }
+
+ else if (it == rteItem) {
+ if (show)
+ mapWidget->showRoutes(gpx.getRoutes());
+ else
+ mapWidget->hideAllRoutes();
+ }
+
+ else {
+ // Individual items, find the right one.
+ GpxItem *git = static_cast<GpxItem *>(it->data().value<void *>());
+ if (git != 0) {
+ git->setVisible(show);
+ for (int i=0; i<gpx.getWaypoints().size(); i++) {
+ if (&gpx.getWaypoints()[i] == git) {
+ mapWidget->setWaypointVisibility(i, show);
+ }
+ }
+ for (int i=0; i<gpx.getTracks().size(); i++) {
+ if (&gpx.getTracks()[i] == git) {
+ mapWidget->setTrackVisibility(i, show);
+ }
+ }
+ for (int i=0; i<gpx.getRoutes().size(); i++) {
+ if (&gpx.getRoutes()[i] == git) {
+ mapWidget->setRouteVisibility(i, show);
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+int GMapDialog::waypointIndex(QStandardItem *it)
+{
+ for (int j=0; j<wptList.size(); j++){
+ if (it == wptList[j])
+ return j;
+ }
+ return -1;
+}
+
+//-------------------------------------------------------------------------
+int GMapDialog::trackIndex(QStandardItem *it)
+{
+ for (int j=0; j<trkList.size(); j++){
+ if (it == trkList[j])
+ return j;
+ }
+ return -1;
+}
+
+//-------------------------------------------------------------------------
+int GMapDialog::routeIndex(QStandardItem *it)
+{
+ for (int j=0; j<rteList.size(); j++){
+ if (it == rteList[j])
+ return j;
+ }
+ return -1;
+}
+
+//-------------------------------------------------------------------------
+void GMapDialog::treeDoubleClicked(const QModelIndex &idx)
+{
+ QStandardItem *it = model->itemFromIndex(idx);
+ int i = waypointIndex(it);
+ if (i >= 0) {
+ it->setCheckState(Qt::Checked);
+ gpx.getWaypoints()[i].setVisible(true);
+ mapWidget->panTo(gpx.getWaypoints()[i].getLocation());
+ mapWidget->setWaypointVisibility(i, true);
+ return;
+ }
+ i = trackIndex(it);
+ if (i >= 0) {
+ mapWidget->frameTrack(i);
+ it->setCheckState(Qt::Checked);
+ gpx.getTracks()[i].setVisible(true);
+ mapWidget->setTrackVisibility(i, true);
+ return;
+ }
+ i = routeIndex(it);
+ if (i >= 0) {
+ mapWidget->frameRoute(i);
+ it->setCheckState(Qt::Checked);
+ gpx.getRoutes()[i].setVisible(true);
+ mapWidget->setRouteVisibility(i, true);
+ return;
+ }
+}
+
+//-------------------------------------------------------------------------
+void GMapDialog::waypointClickedX(int i)
+{
+ if (i>=0 && i < wptList.size()) {
+ QStandardItem *it = wptList[i];
+ QModelIndex idx = model->indexFromItem(it);
+ ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
+ ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
+ }
+}
+//-------------------------------------------------------------------------
+void GMapDialog::trackClickedX(int i)
+{
+ if (i>=0 && i <trkList.size()) {
+ QStandardItem *it = trkList[i];
+ QModelIndex idx = model->indexFromItem(it);
+ ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
+ ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+//-------------------------------------------------------------------------
+void GMapDialog::routeClickedX(int i)
+{
+ if (i>=0 && i <rteList.size()) {
+ QStandardItem *it = rteList[i];
+ QModelIndex idx = model->indexFromItem(it);
+ ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
+ ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
+ }
+}
+
+//-------------------------------------------------------------------------
+void GMapDialog::selectionChangedX (const QItemSelection &sel, const QItemSelection &desel)
+{
+ int k=0;
+ foreach (QStandardItem*w, wptList) {
+ QModelIndex idx = model->indexFromItem(w);
+ if (desel.contains(idx))
+ mapWidget->setWaypointColorBlue(k);
+ if (sel.contains(idx))
+ mapWidget->setWaypointColorRed(k);
+ k++;
+ }
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::expandCollapseAll(const QList<QStandardItem *> &li,
+ QStandardItem *top, bool exp)
+{
+ ui.treeView->setExpanded(model->indexFromItem(top), exp);
+ foreach (QStandardItem*it, li) {
+ QModelIndex idx = model->indexFromItem(it);
+ ui.treeView->setExpanded(idx, exp);
+ }
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::expandAllWaypoints()
+{
+ expandCollapseAll(wptList, wptItem, true);
+}
+//------------------------------------------------------------------------
+void GMapDialog::expandAllTracks()
+{
+ expandCollapseAll(trkList, trkItem, true);
+}
+//------------------------------------------------------------------------
+void GMapDialog::expandAllRoutes()
+{
+ expandCollapseAll(rteList, rteItem, true);
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::collapseAllWaypoints()
+{
+ expandCollapseAll(wptList, wptItem,false);
+}
+//------------------------------------------------------------------------
+void GMapDialog::collapseAllTracks()
+{
+ expandCollapseAll(trkList, trkItem,false);
+}
+//------------------------------------------------------------------------
+void GMapDialog::collapseAllRoutes()
+{
+ expandCollapseAll(rteList, rteItem,false);
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::checkUncheckAll(const QList<QStandardItem *> &li,
+ QStandardItem *top, bool ck)
+{
+ top->setCheckState(ck ? Qt::Checked: Qt::Unchecked);
+ foreach (QStandardItem*it, li) {
+ it->setCheckState(ck ? Qt::Checked: Qt::Unchecked);
+ }
+}
+//------------------------------------------------------------------------
+void GMapDialog::showAllWaypoints()
+{
+ foreach (GpxWaypoint wpt, gpx.getWaypoints())
+ wpt.setVisible(true);
+ checkUncheckAll(wptList, wptItem, true);
+ mapWidget->showWaypoints(gpx.getWaypoints());
+}
+//------------------------------------------------------------------------
+void GMapDialog::showAllTracks()
+{
+ foreach (GpxTrack trk, gpx.getTracks())
+ trk.setVisible(true);
+ checkUncheckAll(trkList, trkItem, true);
+ mapWidget->showTracks(gpx.getTracks());
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::showAllRoutes()
+{
+ foreach (GpxRoute rte, gpx.getRoutes())
+ rte.setVisible(true);
+ checkUncheckAll(rteList, rteItem, true);
+ mapWidget->showRoutes(gpx.getRoutes());
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::hideAllWaypoints()
+{
+ foreach (GpxWaypoint wpt, gpx.getWaypoints())
+ wpt.setVisible(false);
+ checkUncheckAll(wptList, wptItem, false);
+ mapWidget->showWaypoints(gpx.getWaypoints());
+}
+//------------------------------------------------------------------------
+void GMapDialog::hideAllTracks()
+{
+ foreach (GpxTrack trk, gpx.getTracks())
+ trk.setVisible(false);
+ checkUncheckAll(trkList, trkItem, false);
+ mapWidget->showTracks(gpx.getTracks());
+
+}
+//------------------------------------------------------------------------
+void GMapDialog::hideAllRoutes()
+{
+ foreach (GpxRoute rte, gpx.getRoutes())
+ rte.setVisible(false);
+ checkUncheckAll(rteList, rteItem, false);
+ mapWidget->showRoutes(gpx.getRoutes());
+
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::showOnlyThisWaypoint()
+{
+ QList <GpxWaypoint> &tlist = gpx.getWaypoints();
+ for (int i=0; i<tlist.size(); i++) {
+ tlist[i].setVisible(i == menuIndex? true: false);
+ trkList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
+ }
+ wptItem->setCheckState(Qt::Checked);
+ mapWidget->showWaypoints(gpx.getWaypoints());
+}
+//------------------------------------------------------------------------
+void GMapDialog::showOnlyThisTrack()
+{
+ QList <GpxTrack> &tlist = gpx.getTracks();
+ for (int i=0; i<tlist.size(); i++) {
+ tlist[i].setVisible(i == menuIndex? true: false);
+ trkList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
+ }
+ trkItem->setCheckState(Qt::Checked);
+ mapWidget->showTracks(gpx.getTracks());
+
+}
+//------------------------------------------------------------------------
+void GMapDialog::showOnlyThisRoute()
+{
+ QList <GpxRoute> &rlist = gpx.getRoutes();
+ for (int i=0; i<rlist.size(); i++) {
+ rlist[i].setVisible(i == menuIndex? true: false);
+ rteList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
+ }
+ rteItem->setCheckState(Qt::Checked);
+ mapWidget->showRoutes(gpx.getRoutes());
+
+}
+
+//------------------------------------------------------------------------
+void GMapDialog::showContextMenu(const QPoint &pt)
+{
+ QModelIndex idx = ui.treeView->indexAt(pt);
+ QStandardItem *it = model->itemFromIndex(idx);
+ int j;
+ if (model->indexFromItem(wptItem) == idx) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show All Waypoints"), this, SLOT(showAllWaypoints()), &menu));
+ menu.addAction(new TreeAction(tr("Hide All Waypoints"), this, SLOT(hideAllWaypoints()),&menu));
+ menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllWaypoints()),&menu));
+ menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllWaypoints()),&menu));
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else if (model->indexFromItem(rteItem) == idx) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show All Routes"), this, SLOT(showAllRoutes()), &menu));
+ menu.addAction(new TreeAction(tr("Hide All Routes"), this, SLOT(hideAllRoutes()),&menu));
+ menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllRoutes()),&menu));
+ menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllRoutes()),&menu));
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else if (model->indexFromItem(trkItem) == idx) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show All Tracks"), this, SLOT(showAllTracks()), &menu));
+ menu.addAction(new TreeAction(tr("Hide All Tracks"), this, SLOT(hideAllTracks()),&menu));
+ menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllTracks()),&menu));
+ menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllTracks()),&menu));
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else if ((j = waypointIndex(it)) >=0) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show Only This Waypoint"), this, SLOT(showOnlyThisWaypoint()), &menu));
+ menuIndex = j;
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else if ((j = trackIndex(it)) >=0) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show Only This Track"), this, SLOT(showOnlyThisTrack()), &menu));
+ menuIndex = j;
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else if ((j = routeIndex(it)) >=0) {
+ QMenu menu(this);
+ menu.addAction(new TreeAction(tr("Show Only This Route"), this, SLOT(showOnlyThisRoute()), &menu));
+ menuIndex = j;
+ menu.exec(ui.treeView->mapToGlobal(pt));
+ }
+ else {
+ }
+}
+//------------------------------------------------------------------------
+void GMapDialog::copyButtonClickedX() {
+
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: gmapdlg.cpp,v 1.3 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-#include <QStandardItemModel>
-#include <QMenu>
-#include <QHeaderView>
-#include "gmapdlg.h"
-#include "appname.h"
-#include "gpx.h"
-
-//------------------------------------------------------------------------
-class StandardItem: public QStandardItem
-{
- public:
- StandardItem(const QString &text): QStandardItem(text)
- {
- this->setEditable(false);
- }
-};
-
-//------------------------------------------------------------------------
-class TreeAction: public QAction
-{
-public:
- TreeAction(const QString &text,
- QObject *obj, const char *member, QObject *parent): QAction(text, parent)
- {
- connect(this, SIGNAL(triggered()), obj, member);
- }
-};
-//------------------------------------------------------------------------
-QString GMapDialog::formatLength(double l)
-{
- double metricLength = l;
- QString metricUnit = tr("meters");
- int metricPrecision = 2;
- if (l > 1000.0) {
- metricLength = l/1000.0;
- metricUnit = "km";
- metricPrecision = 3;
- }
-
- double fpsLength = l*1000.0/25.4/12.0;
- QString fpsUnit = tr("feet");
- int fpsPrecision = 1;
- if (fpsLength >5280.0) {
- fpsLength /= 5280.0;
- fpsUnit = tr("miles");
- fpsPrecision = 3;
- }
- return QString(tr("Length: %1 %2\n %3 %4")
- .arg(metricLength, 0, 'f', metricPrecision)
- .arg(metricUnit)
- .arg(fpsLength, 0, 'f', fpsPrecision)
- .arg(fpsUnit));
-
-}
-//------------------------------------------------------------------------
-void GMapDialog::appendWaypointInfo(QStandardItem *it, const GpxWaypoint &wpt)
-{
- it->appendRow(new StandardItem(tr("Lat: %1").arg(wpt.getLocation().lat(), 0, 'f', 7)));
- it->appendRow(new StandardItem(tr("Lng: %1").arg(wpt.getLocation().lng(), 0, 'f', 7)));
- if (wpt.getDescription() != QString())
- it->appendRow(new StandardItem(tr("Desc: %1").arg(wpt.getDescription())));
- if (wpt.getComment() != QString() && wpt.getComment() != wpt.getDescription())
- it->appendRow(new StandardItem(tr("Cmt: %1").arg(wpt.getComment())));
- if (wpt.getElevation() > -50000)
- it->appendRow(new StandardItem(tr("Ele: %1").arg(wpt.getElevation())));
-
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::appendTrackInfo(QStandardItem *it, const GpxTrack &trk)
-{
- QDateTime startTime, stopTime;
- bool first = true;
- int count = 0;
- foreach (const GpxTrackSegment &seg, trk.getTrackSegments()) {
- foreach (const GpxTrackPoint &pt, seg.getTrackPoints()) {
- count++;
- QDateTime t = pt.getDateTime();
- if (!t.isValid())
- continue;
- if (first) {
- startTime = t;
- stopTime = t;
- first = false;
- }
- else {
- if (t < startTime)
- startTime = t;
- if (t > stopTime)
- stopTime = t;
- }
- }
- }
- if (startTime.isValid()) {
- it->appendRow(new StandardItem(tr("Start: %1")
- .arg(startTime.toString("yyyy-MMM-dd HH:mm:ss"))));
- it->appendRow(new StandardItem(tr("Stop: %1")
- .arg(stopTime.toString("yyyy-MMM-dd HH:mm:ss"))));
- }
- it->appendRow(new StandardItem(tr("Points: %1").arg(count)));
-
- it->appendRow(new StandardItem(formatLength(trk.length())));
-
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::appendRouteInfo(QStandardItem *it, const GpxRoute &rte)
-{
- it->appendRow(new StandardItem(formatLength(rte.length())));
-}
-
-//------------------------------------------------------------------------
-GMapDialog::GMapDialog(QWidget *parent, const QString &gpxFileName, QPlainTextEdit *te): QDialog(parent)
-{
- ui.setupUi(this);
- this->setWindowTitle(QString(appName) + " " + QString("Google Maps"));
- gpx.read(gpxFileName);
-
- mapWidget = new Map(this, gpx, te);
- QHBoxLayout *lay = new QHBoxLayout(ui.frame);
- lay->setContentsMargins(0, 0, 0, 0);
- lay->addWidget(mapWidget);
-
- model = new QStandardItemModel(this);
-
- wptItem = new StandardItem(tr("Waypoints"));
- wptItem->setCheckable(true);
- wptItem->setCheckState(Qt::Checked);
- model->appendRow(wptItem);
- for (int i=0; i<gpx.getWaypoints().size(); i++) {
- GpxWaypoint &wpt = gpx.getWaypoints()[i];
- QStandardItem *it = new StandardItem(wpt.getName());
- wptItem->appendRow(it);
- it->setCheckable(true);
- it->setCheckState(Qt::Checked);
- it->setData(qVariantFromValue((void *)&wpt));
- appendWaypointInfo(it, wpt);
- wptList << it;
- }
-
- trkItem = new StandardItem(tr("Tracks"));
- trkItem->setCheckable(true);
- trkItem->setCheckState(Qt::Checked);
- model->appendRow(trkItem);
- for (int i=0; i<gpx.getTracks().size(); i++) {
- GpxTrack &trk = gpx.getTracks()[i];
- QStandardItem *it = new StandardItem(trk.getName());
- trkItem->appendRow(it);
- it->setCheckable(true);
- it->setCheckState(Qt::Checked);
- it->setData(qVariantFromValue((void *)&trk));
- appendTrackInfo(it, trk);
- trkList << it;
- }
-
- rteItem = new StandardItem(tr("Routes"));
- rteItem->setCheckable(true);
- rteItem->setCheckState(Qt::Checked);
- model->appendRow(rteItem);
- for (int i=0; i<gpx.getRoutes().size(); i++) {
- GpxRoute &rte = gpx.getRoutes()[i];
- QStandardItem *it = new StandardItem(rte.getName());
- rteItem->appendRow(it);
- it->setCheckable(true);
- it->setCheckState(Qt::Checked);
- it->setData(qVariantFromValue((void *)&rte));
- appendRouteInfo(it, rte);
- rteList << it;
- }
-
- ui.treeView->header()->hide();
- ui.treeView->setModel(model);
- ui.treeView->setExpandsOnDoubleClick(false);
- connect(model, SIGNAL(itemChanged(QStandardItem *)),
- this, SLOT(itemChangedX(QStandardItem *)));
- connect(mapWidget, SIGNAL(waypointClicked(int)), this, SLOT(waypointClickedX(int)));
- connect(mapWidget, SIGNAL(routeClicked(int)), this, SLOT(routeClickedX(int)));
- connect(mapWidget, SIGNAL(trackClicked(int)), this, SLOT(trackClickedX(int)));
- connect(ui.treeView, SIGNAL(doubleClicked(const QModelIndex &)),
- this, SLOT(treeDoubleClicked(const QModelIndex&)));
- connect(ui.treeView->selectionModel(), SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
- this, SLOT(selectionChangedX(const QItemSelection &, const QItemSelection &)));
-
- ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui.treeView, SIGNAL(customContextMenuRequested(const QPoint &)),
- this, SLOT(showContextMenu(const QPoint &)));
-
- connect(ui.copyButton, SIGNAL(clicked()), this, SLOT(copyButtonClickedX()));
-
- ui.copyButton->hide(); // Hide for now, not working
-
-}
-
-//-------------------------------------------------------------------------
-void GMapDialog::itemChangedX(QStandardItem *it)
-{
- bool show = (it->checkState() == Qt::Checked);
- if (it == trkItem) {
- if (show)
- mapWidget->showTracks(gpx.getTracks());
- else
- mapWidget->hideAllTracks();
- }
-
- else if (it == wptItem) {
- if (show)
- mapWidget->showWaypoints(gpx.getWaypoints());
- else
- mapWidget->hideAllWaypoints();
- }
-
- else if (it == rteItem) {
- if (show)
- mapWidget->showRoutes(gpx.getRoutes());
- else
- mapWidget->hideAllRoutes();
- }
-
- else {
- // Individual items, find the right one.
- GpxItem *git = static_cast<GpxItem *>(it->data().value<void *>());
- if (git != 0) {
- git->setVisible(show);
- for (int i=0; i<gpx.getWaypoints().size(); i++) {
- if (&gpx.getWaypoints()[i] == git) {
- mapWidget->setWaypointVisibility(i, show);
- }
- }
- for (int i=0; i<gpx.getTracks().size(); i++) {
- if (&gpx.getTracks()[i] == git) {
- mapWidget->setTrackVisibility(i, show);
- }
- }
- for (int i=0; i<gpx.getRoutes().size(); i++) {
- if (&gpx.getRoutes()[i] == git) {
- mapWidget->setRouteVisibility(i, show);
- }
- }
- }
- }
-}
-
-//-------------------------------------------------------------------------
-int GMapDialog::waypointIndex(QStandardItem *it)
-{
- for (int j=0; j<wptList.size(); j++){
- if (it == wptList[j])
- return j;
- }
- return -1;
-}
-
-//-------------------------------------------------------------------------
-int GMapDialog::trackIndex(QStandardItem *it)
-{
- for (int j=0; j<trkList.size(); j++){
- if (it == trkList[j])
- return j;
- }
- return -1;
-}
-
-//-------------------------------------------------------------------------
-int GMapDialog::routeIndex(QStandardItem *it)
-{
- for (int j=0; j<rteList.size(); j++){
- if (it == rteList[j])
- return j;
- }
- return -1;
-}
-
-//-------------------------------------------------------------------------
-void GMapDialog::treeDoubleClicked(const QModelIndex &idx)
-{
- QStandardItem *it = model->itemFromIndex(idx);
- int i = waypointIndex(it);
- if (i >= 0) {
- it->setCheckState(Qt::Checked);
- gpx.getWaypoints()[i].setVisible(true);
- mapWidget->panTo(gpx.getWaypoints()[i].getLocation());
- mapWidget->setWaypointVisibility(i, true);
- return;
- }
- i = trackIndex(it);
- if (i >= 0) {
- mapWidget->frameTrack(i);
- it->setCheckState(Qt::Checked);
- gpx.getTracks()[i].setVisible(true);
- mapWidget->setTrackVisibility(i, true);
- return;
- }
- i = routeIndex(it);
- if (i >= 0) {
- mapWidget->frameRoute(i);
- it->setCheckState(Qt::Checked);
- gpx.getRoutes()[i].setVisible(true);
- mapWidget->setRouteVisibility(i, true);
- return;
- }
-}
-
-//-------------------------------------------------------------------------
-void GMapDialog::waypointClickedX(int i)
-{
- if (i>=0 && i < wptList.size()) {
- QStandardItem *it = wptList[i];
- QModelIndex idx = model->indexFromItem(it);
- ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
- ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
- }
-}
-//-------------------------------------------------------------------------
-void GMapDialog::trackClickedX(int i)
-{
- if (i>=0 && i <trkList.size()) {
- QStandardItem *it = trkList[i];
- QModelIndex idx = model->indexFromItem(it);
- ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
- ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
- }
-}
-
-//-------------------------------------------------------------------------
-void GMapDialog::routeClickedX(int i)
-{
- if (i>=0 && i <rteList.size()) {
- QStandardItem *it = rteList[i];
- QModelIndex idx = model->indexFromItem(it);
- ui.treeView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
- ui.treeView->selectionModel()->select(idx, QItemSelectionModel::ClearAndSelect);
- }
-}
-
-//-------------------------------------------------------------------------
-void GMapDialog::selectionChangedX (const QItemSelection &sel, const QItemSelection &desel)
-{
- int k=0;
- foreach (QStandardItem*w, wptList) {
- QModelIndex idx = model->indexFromItem(w);
- if (desel.contains(idx))
- mapWidget->setWaypointColorBlue(k);
- if (sel.contains(idx))
- mapWidget->setWaypointColorRed(k);
- k++;
- }
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::expandCollapseAll(const QList<QStandardItem *> &li,
- QStandardItem *top, bool exp)
-{
- ui.treeView->setExpanded(model->indexFromItem(top), exp);
- foreach (QStandardItem*it, li) {
- QModelIndex idx = model->indexFromItem(it);
- ui.treeView->setExpanded(idx, exp);
- }
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::expandAllWaypoints()
-{
- expandCollapseAll(wptList, wptItem, true);
-}
-//------------------------------------------------------------------------
-void GMapDialog::expandAllTracks()
-{
- expandCollapseAll(trkList, trkItem, true);
-}
-//------------------------------------------------------------------------
-void GMapDialog::expandAllRoutes()
-{
- expandCollapseAll(rteList, rteItem, true);
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::collapseAllWaypoints()
-{
- expandCollapseAll(wptList, wptItem,false);
-}
-//------------------------------------------------------------------------
-void GMapDialog::collapseAllTracks()
-{
- expandCollapseAll(trkList, trkItem,false);
-}
-//------------------------------------------------------------------------
-void GMapDialog::collapseAllRoutes()
-{
- expandCollapseAll(rteList, rteItem,false);
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::checkUncheckAll(const QList<QStandardItem *> &li,
- QStandardItem *top, bool ck)
-{
- top->setCheckState(ck ? Qt::Checked: Qt::Unchecked);
- foreach (QStandardItem*it, li) {
- it->setCheckState(ck ? Qt::Checked: Qt::Unchecked);
- }
-}
-//------------------------------------------------------------------------
-void GMapDialog::showAllWaypoints()
-{
- foreach (GpxWaypoint wpt, gpx.getWaypoints())
- wpt.setVisible(true);
- checkUncheckAll(wptList, wptItem, true);
- mapWidget->showWaypoints(gpx.getWaypoints());
-}
-//------------------------------------------------------------------------
-void GMapDialog::showAllTracks()
-{
- foreach (GpxTrack trk, gpx.getTracks())
- trk.setVisible(true);
- checkUncheckAll(trkList, trkItem, true);
- mapWidget->showTracks(gpx.getTracks());
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::showAllRoutes()
-{
- foreach (GpxRoute rte, gpx.getRoutes())
- rte.setVisible(true);
- checkUncheckAll(rteList, rteItem, true);
- mapWidget->showRoutes(gpx.getRoutes());
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::hideAllWaypoints()
-{
- foreach (GpxWaypoint wpt, gpx.getWaypoints())
- wpt.setVisible(false);
- checkUncheckAll(wptList, wptItem, false);
- mapWidget->showWaypoints(gpx.getWaypoints());
-}
-//------------------------------------------------------------------------
-void GMapDialog::hideAllTracks()
-{
- foreach (GpxTrack trk, gpx.getTracks())
- trk.setVisible(false);
- checkUncheckAll(trkList, trkItem, false);
- mapWidget->showTracks(gpx.getTracks());
-
-}
-//------------------------------------------------------------------------
-void GMapDialog::hideAllRoutes()
-{
- foreach (GpxRoute rte, gpx.getRoutes())
- rte.setVisible(false);
- checkUncheckAll(rteList, rteItem, false);
- mapWidget->showRoutes(gpx.getRoutes());
-
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::showOnlyThisWaypoint()
-{
- QList <GpxWaypoint> &tlist = gpx.getWaypoints();
- for (int i=0; i<tlist.size(); i++) {
- tlist[i].setVisible(i == menuIndex? true: false);
- trkList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
- }
- wptItem->setCheckState(Qt::Checked);
- mapWidget->showWaypoints(gpx.getWaypoints());
-}
-//------------------------------------------------------------------------
-void GMapDialog::showOnlyThisTrack()
-{
- QList <GpxTrack> &tlist = gpx.getTracks();
- for (int i=0; i<tlist.size(); i++) {
- tlist[i].setVisible(i == menuIndex? true: false);
- trkList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
- }
- trkItem->setCheckState(Qt::Checked);
- mapWidget->showTracks(gpx.getTracks());
-
-}
-//------------------------------------------------------------------------
-void GMapDialog::showOnlyThisRoute()
-{
- QList <GpxRoute> &rlist = gpx.getRoutes();
- for (int i=0; i<rlist.size(); i++) {
- rlist[i].setVisible(i == menuIndex? true: false);
- rteList[i]->setCheckState(i==menuIndex? Qt::Checked: Qt::Unchecked);
- }
- rteItem->setCheckState(Qt::Checked);
- mapWidget->showRoutes(gpx.getRoutes());
-
-}
-
-//------------------------------------------------------------------------
-void GMapDialog::showContextMenu(const QPoint &pt)
-{
- QModelIndex idx = ui.treeView->indexAt(pt);
- QStandardItem *it = model->itemFromIndex(idx);
- int j;
- if (model->indexFromItem(wptItem) == idx) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show All Waypoints"), this, SLOT(showAllWaypoints()), &menu));
- menu.addAction(new TreeAction(tr("Hide All Waypoints"), this, SLOT(hideAllWaypoints()),&menu));
- menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllWaypoints()),&menu));
- menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllWaypoints()),&menu));
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else if (model->indexFromItem(rteItem) == idx) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show All Routes"), this, SLOT(showAllRoutes()), &menu));
- menu.addAction(new TreeAction(tr("Hide All Routes"), this, SLOT(hideAllRoutes()),&menu));
- menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllRoutes()),&menu));
- menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllRoutes()),&menu));
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else if (model->indexFromItem(trkItem) == idx) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show All Tracks"), this, SLOT(showAllTracks()), &menu));
- menu.addAction(new TreeAction(tr("Hide All Tracks"), this, SLOT(hideAllTracks()),&menu));
- menu.addAction(new TreeAction(tr("Expand All"), this, SLOT(expandAllTracks()),&menu));
- menu.addAction(new TreeAction(tr("Collapse All"), this, SLOT(collapseAllTracks()),&menu));
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else if ((j = waypointIndex(it)) >=0) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show Only This Waypoint"), this, SLOT(showOnlyThisWaypoint()), &menu));
- menuIndex = j;
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else if ((j = trackIndex(it)) >=0) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show Only This Track"), this, SLOT(showOnlyThisTrack()), &menu));
- menuIndex = j;
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else if ((j = routeIndex(it)) >=0) {
- QMenu menu(this);
- menu.addAction(new TreeAction(tr("Show Only This Route"), this, SLOT(showOnlyThisRoute()), &menu));
- menuIndex = j;
- menu.exec(ui.treeView->mapToGlobal(pt));
- }
- else {
- }
-}
-//------------------------------------------------------------------------
-void GMapDialog::copyButtonClickedX() {
-
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: gpx.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+
+#include <QFile>
+#include <QXmlInputSource>
+#include <QXmlSimpleReader>
+#include <QXmlDefaultHandler>
+#include "gpx.h"
+
+
+static QDateTime decodeDateTime(const QString s)
+{
+ QDateTime utc = QDateTime::fromString(s, "yyyy-MM-dd'T'HH:mm:ss'Z'");
+ return utc;
+}
+
+static bool trackIsEmpty(const GpxTrack &trk){
+ int count = 0;
+ for (int i=0; i< trk.getTrackSegments().size(); i++) {
+ for (int j=0; j<trk.getTrackSegments()[i].getTrackPoints().size(); j++) {
+ count++;
+ }
+ }
+ return count <=2 ;
+}
+
+class GpxHandler: public QXmlDefaultHandler
+{
+public:
+ GpxHandler(): QXmlDefaultHandler()
+
+ {
+ state = e_noop;
+ }
+
+ typedef enum {e_noop, e_wpt, e_trk,
+ e_trkpt, e_trkseg, e_rte, e_rtept} elementState;
+ QString textChars;
+ GpxWaypoint currentWpt;
+ QList <GpxWaypoint> wptList;
+
+ QList <GpxTrack> trkList;
+ GpxTrack currentTrk;
+ GpxTrackPoint currentTrkPt;
+ GpxTrackSegment currentTrkSeg;
+
+ QList <GpxRoute> rteList;
+ GpxRoute currentRte;
+ GpxRoutePoint currentRtePt;
+
+ elementState state;
+ QList <elementState> stateStack;
+
+ virtual bool startElement (const QString & ,
+ const QString & localName, const QString & qName,
+ const QXmlAttributes & atts )
+ {
+ if (localName == "wpt") {
+ currentWpt = GpxWaypoint();
+ double lat = atts.value("lat").toDouble();;
+ double lon = atts.value("lon").toDouble();;
+ currentWpt.setLocation(LatLng(lat, lon));
+ stateStack << state;
+ state = e_wpt;
+ }
+
+ else if (localName == "trk") {
+ stateStack << state;
+ state = e_trk;
+ currentTrk.clear();
+ }
+
+ else if (localName == "trkseg") {
+ stateStack << state;
+ state = e_trkseg;
+ currentTrkSeg.clear();
+ }
+
+ else if (localName == "trkpt") {
+ currentTrkPt = GpxTrackPoint();
+ double lat = atts.value("lat").toDouble();;
+ double lon = atts.value("lon").toDouble();;
+ currentTrkPt.setLocation(LatLng(lat, lon));
+ stateStack << state;
+ state = e_trkpt;
+ }
+
+ else if (localName == "rte") {
+ stateStack << state;
+ state = e_rte;
+ currentRte.clear();
+ }
+
+ else if (localName == "rtept") {
+ currentRtePt = GpxRoutePoint();
+ double lat = atts.value("lat").toDouble();;
+ double lon = atts.value("lon").toDouble();;
+ currentRtePt.setLocation(LatLng(lat, lon));
+ stateStack << state;
+ state = e_rtept;
+ }
+
+
+ else if (state == e_wpt ||
+ state == e_trkpt || state == e_trkseg || state == e_trk ||
+ state == e_rte || state == e_rtept) {
+ }
+ else {
+ //fprintf(stderr, "localName: %s name: %s\n",
+ //localName.toStdString().c_str(), qName.toStdString().c_str());
+ }
+ return true;
+ };
+
+ virtual bool endElement (const QString & ,
+ const QString & localName,
+ const QString & qName)
+ {
+ if (localName == "wpt") {
+ state = stateStack.takeLast();
+ wptList << currentWpt;
+ }
+ else if (localName == "ele" && state == e_wpt) {
+ currentWpt.setElevation(textChars.toDouble());
+ }
+ else if (localName == "name" && state == e_wpt) {
+ currentWpt.setName(textChars);
+ }
+ else if (localName == "cmt" && state == e_wpt) {
+ currentWpt.setComment(textChars);
+ }
+ else if (localName == "desc" && state == e_wpt) {
+ currentWpt.setDescription(textChars);
+ }
+ else if (localName == "sym" && state == e_wpt) {
+ currentWpt.setSymbol(textChars);
+ }
+
+ else if (localName == "trkpt") {
+ state = stateStack.takeLast();
+ currentTrkSeg.addPoint(currentTrkPt);
+ }
+ else if (localName == "ele" && state == e_trkpt) {
+ currentTrkPt.setElevation(textChars.toDouble());
+ }
+ else if (localName == "time" && state == e_trkpt) {
+ currentTrkPt.setDateTime(decodeDateTime(textChars));
+ }
+
+ else if (localName == "trkseg") {
+ state = stateStack.takeLast();
+ currentTrk.addSegment(currentTrkSeg);
+ }
+
+ else if (localName == "trk") {
+ state = stateStack.takeLast();
+ if (!trackIsEmpty(currentTrk))
+ trkList << currentTrk;
+ }
+
+ else if (localName == "name" && state == e_trk) {
+ currentTrk.setName(textChars);
+ }
+ else if (localName == "number" && state == e_trk) {
+ currentTrk.setNumber(textChars.toInt());
+ }
+
+ else if (localName == "rte") {
+ state = stateStack.takeLast();
+ if (currentRte.getRoutePoints().size()>=2)
+ rteList << currentRte;
+ }
+
+ else if (localName == "rtept") {
+ state = stateStack.takeLast();
+ currentRte.addPoint(currentRtePt);
+ }
+
+ else if (localName == "name" && state == e_rtept) {
+ currentRtePt.setName(textChars);
+ }
+
+ else if (localName == "name" && state == e_rte) {
+ currentRte.setName(textChars);
+ }
+
+ else {
+ //fprintf(stderr, "end ---- localName: %s name: %s\n\n",
+ //localName.toStdString().c_str(), qName.toStdString().c_str());
+ }
+ return true;
+ };
+
+ virtual bool characters(const QString &x)
+ {
+ textChars = x;
+ return true;
+ };
+};
+
+
+//------------------------------------------------------------------------
+
+bool Gpx::read(const QString & fileName)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly))
+ return false;
+
+ QXmlInputSource xmlIn(&file);
+
+ QXmlSimpleReader reader;
+ GpxHandler gpxHandler;
+ reader.setContentHandler(&gpxHandler);
+
+ if (reader.parse(xmlIn)) {
+ wayPoints = gpxHandler.wptList;
+ tracks = gpxHandler.trkList;
+ routes = gpxHandler.rteList;
+ return true;
+ }
+ else
+ return false;
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: gpx.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-
-#include <QFile>
-#include <QXmlInputSource>
-#include <QXmlSimpleReader>
-#include <QXmlDefaultHandler>
-#include "gpx.h"
-
-
-static QDateTime decodeDateTime(const QString s)
-{
- QDateTime utc = QDateTime::fromString(s, "yyyy-MM-dd'T'HH:mm:ss'Z'");
- return utc;
-}
-
-static bool trackIsEmpty(const GpxTrack &trk){
- int count = 0;
- for (int i=0; i< trk.getTrackSegments().size(); i++) {
- for (int j=0; j<trk.getTrackSegments()[i].getTrackPoints().size(); j++) {
- count++;
- }
- }
- return count <=2 ;
-}
-
-class GpxHandler: public QXmlDefaultHandler
-{
-public:
- GpxHandler(): QXmlDefaultHandler()
-
- {
- state = e_noop;
- }
-
- typedef enum {e_noop, e_wpt, e_trk,
- e_trkpt, e_trkseg, e_rte, e_rtept} elementState;
- QString textChars;
- GpxWaypoint currentWpt;
- QList <GpxWaypoint> wptList;
-
- QList <GpxTrack> trkList;
- GpxTrack currentTrk;
- GpxTrackPoint currentTrkPt;
- GpxTrackSegment currentTrkSeg;
-
- QList <GpxRoute> rteList;
- GpxRoute currentRte;
- GpxRoutePoint currentRtePt;
-
- elementState state;
- QList <elementState> stateStack;
-
- virtual bool startElement (const QString & ,
- const QString & localName, const QString & qName,
- const QXmlAttributes & atts )
- {
- if (localName == "wpt") {
- currentWpt = GpxWaypoint();
- double lat = atts.value("lat").toDouble();;
- double lon = atts.value("lon").toDouble();;
- currentWpt.setLocation(LatLng(lat, lon));
- stateStack << state;
- state = e_wpt;
- }
-
- else if (localName == "trk") {
- stateStack << state;
- state = e_trk;
- currentTrk.clear();
- }
-
- else if (localName == "trkseg") {
- stateStack << state;
- state = e_trkseg;
- currentTrkSeg.clear();
- }
-
- else if (localName == "trkpt") {
- currentTrkPt = GpxTrackPoint();
- double lat = atts.value("lat").toDouble();;
- double lon = atts.value("lon").toDouble();;
- currentTrkPt.setLocation(LatLng(lat, lon));
- stateStack << state;
- state = e_trkpt;
- }
-
- else if (localName == "rte") {
- stateStack << state;
- state = e_rte;
- currentRte.clear();
- }
-
- else if (localName == "rtept") {
- currentRtePt = GpxRoutePoint();
- double lat = atts.value("lat").toDouble();;
- double lon = atts.value("lon").toDouble();;
- currentRtePt.setLocation(LatLng(lat, lon));
- stateStack << state;
- state = e_rtept;
- }
-
-
- else if (state == e_wpt ||
- state == e_trkpt || state == e_trkseg || state == e_trk ||
- state == e_rte || state == e_rtept) {
- }
- else {
- //fprintf(stderr, "localName: %s name: %s\n",
- //localName.toStdString().c_str(), qName.toStdString().c_str());
- }
- return true;
- };
-
- virtual bool endElement (const QString & ,
- const QString & localName,
- const QString & qName)
- {
- if (localName == "wpt") {
- state = stateStack.takeLast();
- wptList << currentWpt;
- }
- else if (localName == "ele" && state == e_wpt) {
- currentWpt.setElevation(textChars.toDouble());
- }
- else if (localName == "name" && state == e_wpt) {
- currentWpt.setName(textChars);
- }
- else if (localName == "cmt" && state == e_wpt) {
- currentWpt.setComment(textChars);
- }
- else if (localName == "desc" && state == e_wpt) {
- currentWpt.setDescription(textChars);
- }
- else if (localName == "sym" && state == e_wpt) {
- currentWpt.setSymbol(textChars);
- }
-
- else if (localName == "trkpt") {
- state = stateStack.takeLast();
- currentTrkSeg.addPoint(currentTrkPt);
- }
- else if (localName == "ele" && state == e_trkpt) {
- currentTrkPt.setElevation(textChars.toDouble());
- }
- else if (localName == "time" && state == e_trkpt) {
- currentTrkPt.setDateTime(decodeDateTime(textChars));
- }
-
- else if (localName == "trkseg") {
- state = stateStack.takeLast();
- currentTrk.addSegment(currentTrkSeg);
- }
-
- else if (localName == "trk") {
- state = stateStack.takeLast();
- if (!trackIsEmpty(currentTrk))
- trkList << currentTrk;
- }
-
- else if (localName == "name" && state == e_trk) {
- currentTrk.setName(textChars);
- }
- else if (localName == "number" && state == e_trk) {
- currentTrk.setNumber(textChars.toInt());
- }
-
- else if (localName == "rte") {
- state = stateStack.takeLast();
- if (currentRte.getRoutePoints().size()>=2)
- rteList << currentRte;
- }
-
- else if (localName == "rtept") {
- state = stateStack.takeLast();
- currentRte.addPoint(currentRtePt);
- }
-
- else if (localName == "name" && state == e_rtept) {
- currentRtePt.setName(textChars);
- }
-
- else if (localName == "name" && state == e_rte) {
- currentRte.setName(textChars);
- }
-
- else {
- //fprintf(stderr, "end ---- localName: %s name: %s\n\n",
- //localName.toStdString().c_str(), qName.toStdString().c_str());
- }
- return true;
- };
-
- virtual bool characters(const QString &x)
- {
- textChars = x;
- return true;
- };
-};
-
-
-//------------------------------------------------------------------------
-
-bool Gpx::read(const QString & fileName)
-{
- QFile file(fileName);
- if (!file.open(QIODevice::ReadOnly))
- return false;
-
- QXmlInputSource xmlIn(&file);
-
- QXmlSimpleReader reader;
- GpxHandler gpxHandler;
- reader.setContentHandler(&gpxHandler);
-
- if (reader.parse(xmlIn)) {
- wayPoints = gpxHandler.wptList;
- tracks = gpxHandler.trkList;
- routes = gpxHandler.rteList;
- return true;
- }
- else
- return false;
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: help.cpp,v 1.8 2009-11-02 20:38:02 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include <QUrl>
+#include <QDesktopServices>
+
+#include "help.h"
+#include "format.h"
+
+//------------------------------------------------------------------------
+void ShowHelp(const QString &urlIn)
+
+{
+ QString url = urlIn;
+ if (!url.contains(QRegExp("^http://"))) {
+ url = Format::getHtmlBase() + url;
+ }
+ QDesktopServices::openUrl(QUrl(url));
+}
+
+
+
+++ /dev/null
-// -*- C++ -*-
-// $Id: help.cpp,v 1.8 2009-11-02 20:38:02 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include <QUrl>
-#include <QDesktopServices>
-
-#include "help.h"
-#include "format.h"
-
-//------------------------------------------------------------------------
-void ShowHelp(const QString &urlIn)
-
-{
- QString url = urlIn;
- if (!url.contains(QRegExp("^http://"))) {
- url = Format::getHtmlBase() + url;
- }
- QDesktopServices::openUrl(QUrl(url));
-}
-
-
-
--- /dev/null
+// -*- C++ -*-
+// $Id: latlng.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include <math.h>
+#include "latlng.h"
+
+
+// copied from the web somewhere.
+static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
+static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
+
+/** @brief Computes the arc, in radian, between two WGS-84 positions.
+ *
+ * The result is equal to <code>Distance(from,to)/EARTH_RADIUS_IN_METERS</code>
+ * <code>= 2*asin(sqrt(h(d/EARTH_RADIUS_IN_METERS )))</code>
+ *
+ * where:<ul>
+ * <li>d is the distance in meters between 'from' and 'to' positions.</li>
+ * <li>h is the haversine function: <code>h(x)=sin²(x/2)</code></li>
+ * </ul>
+ *
+ * The haversine formula gives:
+ * <code>h(d/R) = h(from.lat-to.lat)+h(from.lon-to.lon)+cos(from.lat)*cos(to.lat)</code>
+ *
+ * @sa http://en.wikipedia.org/wiki/Law_of_haversines
+ */
+static double ArcInRadians(const LatLng& from, const LatLng& to)
+{
+ double latitudeArc = (from.lat() - to.lat()) * DEG_TO_RAD;
+ double longitudeArc = (from.lng() - to.lng()) * DEG_TO_RAD;
+ double latitudeH = sin(latitudeArc * 0.5);
+ latitudeH *= latitudeH;
+ double lontitudeH = sin(longitudeArc * 0.5);
+ lontitudeH *= lontitudeH;
+ double tmp = cos(from.lat()*DEG_TO_RAD) * cos(to.lat()*DEG_TO_RAD);
+ return 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
+}
+
+/** @brief Computes the distance, in meters, between two WGS-84 positions.
+ *
+ * The result is equal to <code>EARTH_RADIUS_IN_METERS*ArcInRadians(from,to)</code>
+ *
+ * @sa ArcInRadians
+ */
+static double DistanceInMeters(const LatLng& from, const LatLng& to) {
+ return EARTH_RADIUS_IN_METERS*ArcInRadians(from, to);
+}
+//------------------------------------------------------------------------
+
+double LatLng::haversineDistance(const LatLng &other) const
+{
+ return DistanceInMeters(*this, other);
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: latlng.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include <math.h>
-#include "latlng.h"
-
-
-// copied from the web somewhere.
-static const double DEG_TO_RAD = 0.017453292519943295769236907684886;
-static const double EARTH_RADIUS_IN_METERS = 6372797.560856;
-
-/** @brief Computes the arc, in radian, between two WGS-84 positions.
- *
- * The result is equal to <code>Distance(from,to)/EARTH_RADIUS_IN_METERS</code>
- * <code>= 2*asin(sqrt(h(d/EARTH_RADIUS_IN_METERS )))</code>
- *
- * where:<ul>
- * <li>d is the distance in meters between 'from' and 'to' positions.</li>
- * <li>h is the haversine function: <code>h(x)=sin²(x/2)</code></li>
- * </ul>
- *
- * The haversine formula gives:
- * <code>h(d/R) = h(from.lat-to.lat)+h(from.lon-to.lon)+cos(from.lat)*cos(to.lat)</code>
- *
- * @sa http://en.wikipedia.org/wiki/Law_of_haversines
- */
-static double ArcInRadians(const LatLng& from, const LatLng& to)
-{
- double latitudeArc = (from.lat() - to.lat()) * DEG_TO_RAD;
- double longitudeArc = (from.lng() - to.lng()) * DEG_TO_RAD;
- double latitudeH = sin(latitudeArc * 0.5);
- latitudeH *= latitudeH;
- double lontitudeH = sin(longitudeArc * 0.5);
- lontitudeH *= lontitudeH;
- double tmp = cos(from.lat()*DEG_TO_RAD) * cos(to.lat()*DEG_TO_RAD);
- return 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
-}
-
-/** @brief Computes the distance, in meters, between two WGS-84 positions.
- *
- * The result is equal to <code>EARTH_RADIUS_IN_METERS*ArcInRadians(from,to)</code>
- *
- * @sa ArcInRadians
- */
-static double DistanceInMeters(const LatLng& from, const LatLng& to) {
- return EARTH_RADIUS_IN_METERS*ArcInRadians(from, to);
-}
-//------------------------------------------------------------------------
-
-double LatLng::haversineDistance(const LatLng &other) const
-{
- return DistanceInMeters(*this, other);
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: main.cpp,v 1.8 2010-06-06 00:49:08 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#define _CRT_SECURE_NO_DEPRECATE 1
+#include <QMessageBox>
+#include <QFile>
+#include <QCoreApplication>
+#include <QLibraryInfo>
+#include <QIcon>
+
+#include "mainwindow.h"
+#include "gmapdlg.h"
+
+#ifdef _WIN32
+const char *pathSeparator = ";";
+#else
+const char *pathSeparator = ":";
+#endif
+
+#if defined (Q_OS_MAC)
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+//------------------------------------------------------------------------
+int main(int argc, char**argv)
+{
+ QApplication *app;
+ app = new QApplication(argc, argv);
+ app->setWindowIcon(QIcon(":/images/appicon.png"));
+
+ QString newPath = "PATH=" + QApplication::applicationDirPath() +
+ QString(pathSeparator) + getenv("PATH");
+ char *newPathEnv = new char[newPath.length() + 1];
+ strcpy(newPathEnv, newPath.toStdString().c_str());
+ putenv(newPathEnv);
+
+ QCoreApplication::setOrganizationName("GPSBabel");
+ QCoreApplication::setOrganizationDomain("gpsbabel.org");
+ QCoreApplication::setApplicationName("GPSBabel");
+
+ MainWindow mainWindow(0);
+ mainWindow.show();
+ app->exec();
+
+ return 0;
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: main.cpp,v 1.8 2010-06-06 00:49:08 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#define _CRT_SECURE_NO_DEPRECATE 1
-#include <QMessageBox>
-#include <QFile>
-#include <QCoreApplication>
-#include <QLibraryInfo>
-#include <QIcon>
-
-#include "mainwindow.h"
-#include "gmapdlg.h"
-
-#ifdef _WIN32
-const char *pathSeparator = ";";
-#else
-const char *pathSeparator = ":";
-#endif
-
-#if defined (Q_OS_MAC)
-#include <CoreFoundation/CoreFoundation.h>
-#endif
-
-//------------------------------------------------------------------------
-int main(int argc, char**argv)
-{
- QApplication *app;
- app = new QApplication(argc, argv);
- app->setWindowIcon(QIcon(":/images/appicon.png"));
-
- QString newPath = "PATH=" + QApplication::applicationDirPath() +
- QString(pathSeparator) + getenv("PATH");
- char *newPathEnv = new char[newPath.length() + 1];
- strcpy(newPathEnv, newPath.toStdString().c_str());
- putenv(newPathEnv);
-
- QCoreApplication::setOrganizationName("GPSBabel");
- QCoreApplication::setOrganizationDomain("gpsbabel.org");
- QCoreApplication::setApplicationName("GPSBabel");
-
- MainWindow mainWindow(0);
- mainWindow.show();
- app->exec();
-
- return 0;
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: mainwindow.cpp,v 1.27 2010-11-01 03:30:42 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+#include <QDesktopServices>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QMimeData>
+#include <QProcess>
+#include <QSettings>
+#include <QTemporaryFile>
+#include <QTextStream>
+
+#include "mainwindow.h"
+#include "../gbversion.h"
+#include "aboutdlg.h"
+#include "advdlg.h"
+#include "appname.h"
+#include "babeldata.h"
+#include "donate.h"
+#include "filterdlg.h"
+#include "formatload.h"
+#include "gmapdlg.h"
+#include "help.h"
+#include "optionsdlg.h"
+#include "preferences.h"
+#include "processwait.h"
+#include "version_mismatch.h"
+#include "upgrade.h"
+
+const int BabelData::noType = -1;
+const int BabelData::fileType = 0;
+const int BabelData::deviceType = 1;
+
+#define FAKE_LANGUAGE_MENU 0
+
+//------------------------------------------------------------------------
+QString MainWindow::findBabelVersion()
+{
+ QProcess babel;
+ babel.start("gpsbabel", QStringList() << "-V");
+ if (!babel.waitForStarted())
+ return QString();
+ babel.closeWriteChannel();
+ if (!babel.waitForFinished())
+ return QString();
+
+ QString str = babel.readAll();
+ is_beta = str.contains("-beta");
+ str.replace("Version", "");
+ str.replace("GPSBabel", "");
+ str.replace(QRegExp("^[\\s]*"), "");
+ str.replace(QRegExp("[\\s]+$"), "");
+ str = str.simplified();
+ return str;
+}
+
+//------------------------------------------------------------------------
+// Decides whether available beta upgrades are suggested to user for download.
+bool MainWindow::allowBetaUpgrades()
+{
+ // If this is a beta version (which means the user consciously downloaded
+ // it and decided to be on the beta track or the user has ticked the
+ // 'suggest beta upgrade' box, allow betas to be suggested for installation.
+ return is_beta || bd.allowBetaUpgrades;
+}
+
+//------------------------------------------------------------------------
+static QStringList getCharSets()
+{
+ QProcess babel;
+ babel.start("gpsbabel", QStringList() << "-l");
+ if (!babel.waitForStarted())
+ return QStringList();
+ babel.closeWriteChannel();
+ if (!babel.waitForFinished())
+ return QStringList();
+
+ QStringList strList;
+ QTextStream tstream(babel.readAll());
+ while(!tstream.atEnd()) {
+ QString l = tstream.readLine();
+ if (QRegExp("^\\*").indexIn(l) == 0) {
+ l.replace(QRegExp("^[\\*\\s]*"), "");
+ l.replace(QRegExp("[\\s]+$"), "");
+ strList << l;
+ }
+ }
+ return strList;
+}
+
+//------------------------------------------------------------------------
+static QString MakeOptions(const QList<FormatOption>& options)
+{
+ QString str;
+ for (int i=0; i<options.size(); i++) {
+ if (options[i].getSelected()) {
+ str += ",";
+ str += options[i].getName();
+ if (options[i].getType() == FormatOption::OPTbool) {
+ str += "=1";
+ } else {
+ str += "=" + options[i].getValue().toString();
+ }
+ } else {
+ if (options[i].getType() == FormatOption::OPTbool) {
+ str += "," + options[i].getName() + "=0";
+ }
+ }
+ }
+ return str;
+}
+
+//------------------------------------------------------------------------
+static QString MakeOptionsNoLeadingComma(const QList<FormatOption>& options)
+{
+ QString str = MakeOptions(options);
+ return (str.length()) ? str.mid(1) : str;
+
+}
+
+//------------------------------------------------------------------------
+MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
+{
+ loadFormats();
+ ui.setupUi(this);
+ setWindowTitle(appName);
+ babelVersion = findBabelVersion();
+ fmtChgInterlock = false;
+ loadDeviceNameCombos();
+ loadCharSetCombos();
+
+ connect(ui.inputFileOptBtn, SIGNAL(clicked()), this, SLOT(inputFileOptBtnClicked()));
+ connect(ui.inputDeviceOptBtn, SIGNAL(clicked()), this, SLOT(inputDeviceOptBtnClicked()));
+ connect(ui.inputFileNameBrowseBtn, SIGNAL(clicked()), this, SLOT(browseInputFile()));
+
+ ui.outputFileOptBtn->setAutoExclusive(false);
+ ui.outputDeviceOptBtn->setAutoExclusive(false);
+ connect(ui.outputFileOptBtn, SIGNAL(clicked()), this, SLOT(outputFileOptBtnClicked()));
+ connect(ui.outputDeviceOptBtn, SIGNAL(clicked()), this, SLOT(outputDeviceOptBtnClicked()));
+ connect(ui.outputFileNameBrowseBtn, SIGNAL(clicked()), this, SLOT(browseOutputFile()));
+
+ connect(ui.actionQuit, SIGNAL(triggered()), this, SLOT(closeActionX()));
+ connect(ui.actionHelp, SIGNAL(triggered()), this, SLOT(helpActionX()));
+ connect(ui.actionAbout, SIGNAL(triggered()), this, SLOT(aboutActionX()));
+ connect(ui.actionVisit_Website, SIGNAL(triggered()), this, SLOT(visitWebsiteActionX()));
+ connect(ui.actionMake_a_Donation, SIGNAL(triggered()), this, SLOT(donateActionX()));
+ connect(ui.actionUpgradeCheck, SIGNAL(triggered()), this, SLOT(upgradeCheckActionX()));
+ connect(ui.actionPreferences, SIGNAL(triggered()), this, SLOT(preferencesActionX()));
+
+ connect(ui.inputFormatCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(inputFormatChanged(int)));
+ connect(ui.outputFormatCombo, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(outputFormatChanged(int)));
+ connect(ui.inputOptionsBtn, SIGNAL(clicked()),
+ this, SLOT(inputOptionButtonClicked()));
+ connect(ui.outputOptionsBtn , SIGNAL(clicked()),
+ this, SLOT(outputOptionButtonClicked()));
+ connect(ui.moreOptionButton , SIGNAL(clicked()),
+ this, SLOT(moreOptionButtonClicked()));
+
+ connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyActionX()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(closeActionX()));
+ connect(ui.xlateFiltersBtn, SIGNAL(clicked()), this, SLOT(filtersClicked()));
+
+ connect(ui.inputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(inputFileNameEdited()));
+ connect(ui.outputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(outputFileNameEdited()));
+
+
+ ui.buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon(":images/runit.png"));
+ ui.buttonBox->button(QDialogButtonBox::Close)->setIcon(QIcon(":images/exit.png"));
+
+
+ ui.inputOptionsText->setReadOnly(true);
+ ui.outputOptionsText->setReadOnly(true);
+#if 0
+ // 02/28/10 - let's try letting people edit these outside the browse.
+ ui.inputFileNameText->setReadOnly(true);
+ ui.outputFileNameText->setReadOnly(true);
+#else
+ setAcceptDrops(true);
+#endif
+ ui.wayPtLabel->setText("");
+ ui.trackLabel->setText("");
+ ui.routeLabel->setText("");
+ lights[0] = QPixmap::fromImage(QImage(":images/00.png").scaledToHeight(20, Qt::SmoothTransformation));
+ lights[1] = QPixmap::fromImage(QImage(":images/01.png").scaledToHeight(20, Qt::SmoothTransformation));
+ lights[2] = QPixmap::fromImage(QImage(":images/10.png").scaledToHeight(20, Qt::SmoothTransformation));
+ lights[3] = QPixmap::fromImage(QImage(":images/11.png").scaledToHeight(20, Qt::SmoothTransformation));
+
+ ui.outputWindow->setReadOnly(true);
+
+ langPath = QApplication::applicationDirPath();
+ langPath.append("/translations/");
+
+ // Start up in the current system language.
+ loadLanguage(QLocale::system().name());
+#if FAKE_LANGUAGE_MENU
+ createLanguageMenu();
+#endif
+
+ //--- Restore from registry
+ restoreSettings();
+
+ upgrade = new UpgradeCheck(parent, formatList, bd);
+ if (bd.startupVersionCheck) {
+ upgrade->checkForUpgrade(babelVersion, bd.upgradeCheckTime,
+ allowBetaUpgrades());
+ }
+
+ if (!bd.ignoreVersionMismatch && babelVersion != VERSION) {
+ VersionMismatch vm(0, babelVersion, QString(VERSION));
+
+ vm.exec();
+ bd.ignoreVersionMismatch = vm.neverAgain();
+ }
+}
+
+//------------------------------------------------------------------------
+MainWindow::~MainWindow()
+{
+ if (upgrade)
+ delete upgrade;
+}
+//------------------------------------------------------------------------
+// Dynamic language switching courtesy of
+// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application
+// We create the menu entries dynamically, dependant on the existing
+// translations.
+#if FAKE_LANGUAGE_MENU
+void MainWindow::createLanguageMenu(void)
+{
+ QActionGroup* langGroup = new QActionGroup(ui.menuHelp);
+ langGroup->setExclusive(true);
+ connect(langGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotLanguageChanged(QAction *)));
+
+ // format systems language
+ QString defaultLocale = QLocale::system().name(); // e.g. "de_DE"
+ defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de"
+
+ QDir dir(langPath);
+ QStringList fileNames = dir.entryList(QStringList("GPSBabelFE*.qm"));
+
+ for (int i = 0; i < fileNames.size(); ++i) {
+ // get locale extracted by filename
+ QString locale;
+ locale = fileNames[i]; // "TranslationExample_de.qm"
+ locale.truncate(locale.lastIndexOf('.')); // "TranslationExample_de"
+ locale.remove(0, locale.indexOf('_') + 1); // "de"
+
+ QString lang = QLocale::languageToString(QLocale(locale).language());
+
+ QAction *action = new QAction(lang, this);
+ action->setCheckable(true);
+ action->setData(locale);
+
+ ui.menuHelp->addAction(action);
+ langGroup->addAction(action);
+
+ // set default translators and language checked
+ if (defaultLocale == locale) {
+ action->setChecked(true);
+ }
+ }
+}
+#endif // FAKE_LANGUAGE_MENU
+
+//------------------------------------------------------------------------
+// Called every time, when a menu entry of the language menu is called
+void MainWindow::slotLanguageChanged(QAction* action)
+{
+ if (0 != action) {
+ // load the language dependant on the action content.
+ loadLanguage(action->data().toString());
+ }
+}
+
+void MainWindow::switchTranslator(QTranslator& translator, const QString& filename)
+{
+ // remove the old translator
+ qApp->removeTranslator(&translator);
+
+ QString full_filename(langPath + "/" + filename);
+
+ // load the new translator
+ if (translator.load(full_filename))
+ qApp->installTranslator(&translator);
+}
+
+void MainWindow::loadLanguage(const QString& rLanguage)
+{
+ if (currLang != rLanguage) {
+ currLang = rLanguage;
+ QLocale locale = QLocale(currLang);
+ QLocale::setDefault(locale);
+ QString languageName = QLocale::languageToString(locale.language());
+
+ switchTranslator(translator, QString("gpsbabelfe_%1.qm").arg(rLanguage));
+ switchTranslator(translatorCore, QString("gpsbabel__%1.qm").arg(rLanguage));
+ switchTranslator(translatorQt, QString("qt_%1.qm").arg(rLanguage));
+ }
+}
+
+void MainWindow::changeEvent(QEvent* event)
+{
+ if (0 != event) {
+ switch(event->type()) {
+ // This event is sent if a translator is loaded.
+ case QEvent::LanguageChange:
+ ui.retranslateUi(this);
+ break;
+ // This event is sent if the system language changes.
+ case QEvent::LocaleChange:
+ {
+ QString locale = QLocale::system().name();
+ locale.truncate(locale.lastIndexOf('_'));
+ loadLanguage(locale);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ QMainWindow::changeEvent(event);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::loadInputDeviceNameCombo(const QString &format)
+{
+ ui.inputDeviceNameCombo->clear();
+ // Later, we can probe the system for multiple USB devices and populate
+ // here.
+ if (formatSupportsUSB(format))
+ ui.inputDeviceNameCombo->addItem("usb:");
+ if (formatSupportsSerial(format))
+ osLoadDeviceNameCombos(ui.inputDeviceNameCombo);
+ // If only one choice, just disable it.
+ ui.inputDeviceNameCombo->setEnabled(ui.inputDeviceNameCombo->count() > 1);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::loadOutputDeviceNameCombo(const QString &format)
+{
+ ui.outputDeviceNameCombo->clear();
+ // Later, we can probe the system for multiple USB devices and populate
+ // here.
+ if (formatSupportsUSB(format))
+ ui.outputDeviceNameCombo->addItem("usb:");
+ if (formatSupportsSerial(format))
+ osLoadDeviceNameCombos(ui.outputDeviceNameCombo);
+ // If only one choice, just disable it.
+ ui.outputDeviceNameCombo->setEnabled(ui.outputDeviceNameCombo->count() > 1);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::loadDeviceNameCombos()
+{
+ loadInputDeviceNameCombo("");
+ loadOutputDeviceNameCombo("");
+}
+//------------------------------------------------------------------------
+void MainWindow::loadCharSetCombos()
+{
+ charSets = getCharSets();
+
+ ui.inputCharSetCombo->clear();
+ ui.outputCharSetCombo->clear();
+ ui.inputCharSetCombo->addItem(tr("default"), QVariant(-1));
+ ui.outputCharSetCombo->addItem(tr("default"), QVariant(-1));
+ for (int i=0; i<charSets.size(); i++) {
+ ui.inputCharSetCombo->addItem(charSets[i], QVariant(i));
+ ui.outputCharSetCombo->addItem(charSets[i], QVariant(i));
+ }
+}
+//------------------------------------------------------------------------
+void MainWindow::checkCharSetCombos()
+{
+ ui.inputCharSetCombo->setEnabled(bd.enableCharSetXform);
+ ui.outputCharSetCombo->setEnabled(bd.enableCharSetXform);
+ ui.inputCharSetCombo->setVisible(bd.enableCharSetXform);
+ ui.outputCharSetCombo->setVisible(bd.enableCharSetXform);
+}
+//------------------------------------------------------------------------
+void MainWindow::inputFileOptBtnClicked()
+{
+ fmtChgInterlock = true;
+ QString fmt = bd.inputFileFormat;
+ ui.inputStackedWidget->setCurrentWidget(ui.inputFilePage);
+ QList<int>indices = inputFileFormatIndices();
+ ui.inputFormatCombo->clear();
+ for (int i=0; i<indices.size(); i++) {
+ int k = indices[i];
+ if (!formatList[k].isHidden())
+ ui.inputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
+ }
+ setComboToFormat(ui.inputFormatCombo, fmt, true);
+ fmtChgInterlock = false;
+}
+
+//------------------------------------------------------------------------
+void MainWindow::inputDeviceOptBtnClicked()
+{
+ fmtChgInterlock = true;
+ QString fmt = bd.inputDeviceFormat;
+ ui.inputStackedWidget->setCurrentWidget(ui.inputDevicePage);
+ QList<int>indices = inputDeviceFormatIndices();
+ ui.inputFormatCombo->clear();
+ for (int i=0; i<indices.size(); i++) {
+ int k = indices[i];
+ if (!formatList[k].isHidden())
+ ui.inputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
+ }
+ setComboToFormat(ui.inputFormatCombo, fmt, false);
+ fmtChgInterlock = false;
+}
+
+//------------------------------------------------------------------------
+void MainWindow:: outputFileOptBtnClicked()
+{
+ fmtChgInterlock = true;
+ if (ui.outputFileOptBtn->isChecked()) {
+ ui.outputFilePage->setEnabled(true);
+ ui.outputDeviceOptBtn->setChecked(false);
+ QString fmt = bd.outputFileFormat;
+ ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
+ QList<int>indices = outputFileFormatIndices();
+ ui.outputFormatCombo->clear();
+ for (int i=0; i<indices.size(); i++) {
+ int k = indices[i];
+ ui.outputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
+ }
+ setComboToFormat(ui.outputFormatCombo, fmt, true);
+ }
+ else {
+ ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
+ ui.outputFilePage->setEnabled(false);
+ }
+ fmtChgInterlock = false;
+}
+
+//------------------------------------------------------------------------
+void MainWindow:: outputDeviceOptBtnClicked()
+{
+ fmtChgInterlock = true;
+ if (ui.outputDeviceOptBtn->isChecked()) {
+ ui.outputDevicePage->setEnabled(true);
+ ui.outputFileOptBtn->setChecked(false);
+ QString fmt = bd.outputDeviceFormat;
+ ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
+ QList<int>indices = outputDeviceFormatIndices();
+ ui.outputFormatCombo->clear();
+ for (int i=0; i<indices.size(); i++) {
+ int k = indices[i];
+ ui.outputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
+ }
+ setComboToFormat(ui.outputFormatCombo, fmt, false);
+ }
+ else {
+ ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
+ ui.outputDevicePage->setEnabled(false);
+ }
+ fmtChgInterlock = false;
+}
+void MainWindow::inputFileNameEdited()
+{
+ bd.inputFileNames.clear();
+ bd.inputFileNames << ui.inputFileNameText->text();
+}
+
+void MainWindow::outputFileNameEdited()
+{
+ bd.outputFileName = ui.outputFileNameText->text();
+
+}
+
+//------------------------------------------------------------------------
+QString MainWindow::filterForFormat(int idx)
+{
+ QString str = formatList[idx].getDescription();
+ str.replace(QRegExp("\\("), "[");
+ str.replace(QRegExp("\\)"), "]");
+ QStringList extensions = formatList[idx].getExtensions();
+
+ // If we don't have any meaningful extensions available for this format,
+ // don't be clever here; just fall through to "All files" case.
+ if (extensions.size() > 0 && !extensions[0].isEmpty()) {
+ str += " (";
+ for (int i=0; i<extensions.size(); i++) {
+ if (i!= 0)
+ str += " ";
+ str += "*." + extensions[i];
+ }
+ str += ");;";
+ }
+ str += "All Files (*.*)";
+ return str;
+}
+//------------------------------------------------------------------------
+QString MainWindow::ensureExtensionPresent(const QString &name, int idx)
+{
+ QString outname = name;
+ if (QFileInfo(name).suffix().length() == 0) {
+ QStringList extensions = formatList[idx].getExtensions();
+ if (extensions.size() > 0)
+ outname += "." + extensions[0];
+ }
+ return outname;
+}
+
+//------------------------------------------------------------------------
+bool MainWindow::filterForFormatIncludes(int idx, const QString &fmt)
+{
+ QStringList extensions = formatList[idx].getExtensions();
+ for (int i=0; i<extensions.size(); i++) {
+ if (fmt == extensions[i])
+ return true;
+ }
+ return false;
+}
+
+//------------------------------------------------------------------------
+int MainWindow::currentComboFormatIndex(QComboBox *comboBox)
+{
+ int idx = comboBox->currentIndex();
+ if (idx<0 || idx >= comboBox->count()) {
+ // QMessageBox::critical(0, appName, "*** Internal Error -- current combo index is invalid!");
+ return 0;
+ }
+ return comboBox->itemData(idx).toInt();
+}
+//------------------------------------------------------------------------
+void MainWindow::browseInputFile()
+{
+ QString startFile = bd.inputFileNames.size() ? bd.inputFileNames[0] : bd.inputBrowse;
+ int idx = currentComboFormatIndex(ui.inputFormatCombo);
+ QFileInfo finfo(startFile);
+ if (!finfo.isDir() && (!filterForFormatIncludes(idx, finfo.suffix()))) {
+ startFile = finfo.dir().absolutePath();
+ }
+
+ QStringList userList =
+ QFileDialog::getOpenFileNames(0, tr("Select one or more input files"),
+ startFile,
+ filterForFormat(idx));
+ if (userList.size()) {
+ bd.inputBrowse = userList[0];
+ bd.inputFileNames = userList;
+ QString str;
+ for (int i=0; i<bd.inputFileNames.size(); i++) {
+ if (i != 0)
+ str += ", ";
+ str += "\"" + bd.inputFileNames[i] + "\"";
+ }
+ ui.inputFileNameText->setText(str);
+ }
+}
+
+//------------------------------------------------------------------------
+void MainWindow::browseOutputFile()
+{
+ int idx = currentComboFormatIndex(ui.outputFormatCombo);
+ QString startFile = bd.outputFileName.length() == 0 ? bd.outputBrowse : bd.outputFileName;
+ QFileInfo finfo(startFile);
+ if (!finfo.isDir() && (!filterForFormatIncludes(idx, finfo.suffix()))) {
+ startFile = finfo.dir().absolutePath();
+ }
+
+ QString str =
+ QFileDialog::getSaveFileName(0, tr("Output File Name"),
+ startFile,
+ filterForFormat(idx));
+ if (str.length() != 0) {
+ str = ensureExtensionPresent(str, idx);
+ bd.outputBrowse = str;
+ bd.outputFileName = str;
+ ui.outputFileNameText->setText(str);
+ }
+}
+
+//------------------------------------------------------------------------
+QList<int> MainWindow::inputFileFormatIndices()
+{
+ QList<int>indices;
+ for (int i=0; i<formatList.size(); i++) {
+ if (formatList[i].isReadSomething() && formatList[i].isFileFormat())
+ indices<<i;
+ }
+ return indices;
+}
+
+//------------------------------------------------------------------------
+QList<int> MainWindow::inputDeviceFormatIndices()
+{
+ QList<int>indices;
+ for (int i=0; i<formatList.size(); i++) {
+ if (formatList[i].isReadSomething() && formatList[i].isDeviceFormat())
+ indices<<i;
+ }
+ return indices;
+}
+
+//------------------------------------------------------------------------
+QList<int> MainWindow::outputFileFormatIndices()
+{
+ QList<int>indices;
+ for (int i=0; i<formatList.size(); i++) {
+ if (formatList[i].isWriteSomething() && formatList[i].isFileFormat())
+ indices<<i;
+ }
+ return indices;
+}
+
+//------------------------------------------------------------------------
+QList<int> MainWindow::outputDeviceFormatIndices()
+{
+ QList<int>indices;
+ for (int i=0; i<formatList.size(); i++) {
+ if (formatList[i].isWriteSomething() && formatList[i].isDeviceFormat())
+ indices<<i;
+ }
+ return indices;
+}
+
+//------------------------------------------------------------------------
+void MainWindow::loadFormats()
+{
+ if (!FormatLoad().getFormats(formatList)) {
+ QMessageBox::information(0, QString(appName),
+ tr("Error reading format configuration. "
+ "Check that the backend program \"gpsbabel\" is properly installed "
+ "and is in the current PATH\n\n"
+ "This program cannot continue."));
+ exit(1);
+ }
+ if (inputFileFormatIndices().size() == 0 ||
+ inputDeviceFormatIndices().size() == 0 ||
+ outputFileFormatIndices().size() == 0 ||
+ outputDeviceFormatIndices().size() == 0) {
+ QMessageBox::information(0, QString(appName),
+ tr("Some file/device formats were not found during initialization. "
+ "Check that the backend program \"gpsbabel\" is properly installed "
+ "and is in the current PATH\n\n"
+ "This program cannot continue."));
+ exit(1);
+ }
+}
+//------------------------------------------------------------------------
+static int iconIndex(bool a, bool b)
+{
+ return ((a?1:0)*2) + (b?1:0);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::setIndicatorLights(QLabel *label, const QString &type, int code)
+{
+ label->setPixmap(lights[code]);
+ QString s;
+ switch (code)
+ {
+ default:
+ case 0:
+ s = tr("Input and output formats do not support %1").arg(type);
+ break;
+ case 1:
+ s = tr("Input does not support %1; output format supports %2").arg(type).arg(type);
+ break;
+ case 2:
+ s = tr("Input format supports %1; output format does not support %2").arg(type).arg(type);
+ break;
+ case 3:
+ s = tr("Both input and output formats support %1").arg(type);
+ break;
+ }
+ label->setToolTip(s);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::crossCheckInOutFormats()
+{
+ if (ui.inputFormatCombo->count() == 0 ||
+ ui.outputFormatCombo->count() == 0) {
+ // During format/device switch this is true
+ return;
+ }
+ Format ifmt = formatList[currentComboFormatIndex(ui.inputFormatCombo)];
+ Format ofmt = formatList[currentComboFormatIndex(ui.outputFormatCombo)];
+
+ ui.xlateWayPtsCk->setEnabled(ifmt.isReadWaypoints() && ofmt.isWriteWaypoints());
+ ui.xlateTracksCk->setEnabled(ifmt.isReadTracks() && ofmt.isWriteTracks());
+ ui.xlateRoutesCk->setEnabled(ifmt.isReadRoutes() && ofmt.isWriteRoutes());
+
+ setIndicatorLights(ui.wayPtLabel, tr("waypoints"), iconIndex(ifmt.isReadWaypoints(), ofmt.isWriteWaypoints()));
+ setIndicatorLights(ui.trackLabel, tr("tracks"), iconIndex(ifmt.isReadTracks(), ofmt.isWriteTracks()));
+ setIndicatorLights(ui.routeLabel, tr("routes"), iconIndex(ifmt.isReadRoutes(), ofmt.isWriteRoutes()));
+}
+
+//------------------------------------------------------------------------
+void MainWindow::displayOptionsText(QLineEdit *le, QComboBox *combo, bool isInput)
+{
+ int fidx = combo->itemData(combo->currentIndex()).toInt();
+ if (isInput)
+ le->setText(MakeOptionsNoLeadingComma(formatList[fidx].getInputOptions()));
+ else
+ le->setText(MakeOptionsNoLeadingComma(formatList[fidx].getOutputOptions()));
+
+}
+
+//------------------------------------------------------------------------
+void MainWindow::setComboToFormat(QComboBox *comboBox, const QString &name, bool isFile)
+{
+ int fidx = -1;
+ for (int i=0; i<formatList.size(); i++) {
+ if (formatList[i].getName() == name &&
+ formatList[i].isFileFormat() == isFile) {
+ fidx = i;
+ break;
+ }
+ }
+ if (fidx >=0) {
+ for (int i=0; i<comboBox->count(); i++) {
+ if (comboBox->itemData(i).toInt() == fidx) {
+ comboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+bool MainWindow::formatSupportsUSB(const QString &format)
+{
+ return (format == "garmin" || format == "delbin");
+}
+
+//------------------------------------------------------------------------
+bool MainWindow::formatSupportsSerial(const QString &format)
+{
+ return (format != "delbin");
+}
+
+//------------------------------------------------------------------------
+void MainWindow::inputFormatChanged(int comboIdx)
+{
+ if (fmtChgInterlock)
+ return;
+ int fidx = ui.inputFormatCombo->itemData(comboIdx).toInt();
+ ui.inputOptionsBtn->setEnabled(formatList[fidx].getInputOptions().size()>0);
+ displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
+ crossCheckInOutFormats();
+
+ if (ui.inputFileOptBtn->isChecked())
+ bd.inputFileFormat =formatList[fidx].getName();
+ else
+ bd.inputDeviceFormat = formatList[fidx].getName();
+
+ loadInputDeviceNameCombo(formatList[fidx].getName());
+}
+
+//------------------------------------------------------------------------
+void MainWindow::outputFormatChanged(int comboIdx)
+{
+ if (fmtChgInterlock)
+ return;
+ int fidx = ui.outputFormatCombo->itemData(comboIdx).toInt();
+ ui.outputOptionsBtn->setEnabled(formatList[fidx].getOutputOptions().size()>0);
+ displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
+ crossCheckInOutFormats();
+
+ if (ui.outputFileOptBtn->isChecked())
+ bd.outputFileFormat =formatList[fidx].getName();
+ else if (ui.outputDeviceOptBtn->isChecked())
+ bd.outputDeviceFormat = formatList[fidx].getName();
+
+ loadOutputDeviceNameCombo(formatList[fidx].getName());
+}
+
+//------------------------------------------------------------------------
+void MainWindow::inputOptionButtonClicked()
+{
+ int fidx = currentComboFormatIndex(ui.inputFormatCombo);
+ if (formatList[fidx].getInputOptionsRef()->size() == 0) {
+ QMessageBox::information
+ (0, appName,
+ tr("There are no input options for format \"%1\"").arg(formatList[fidx].getDescription()));
+ }
+ else {
+ OptionsDlg optionDlg(0,
+ formatList[fidx].getName(),
+ formatList[fidx].getInputOptionsRef(),
+ formatList[fidx].getHtml());
+ optionDlg.setWindowTitle(QString(appName) + " - " + tr("Options for %1").arg(formatList[fidx].getName()));
+ optionDlg.exec();
+ displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
+ }
+}
+
+//------------------------------------------------------------------------
+void MainWindow::outputOptionButtonClicked()
+{
+ int fidx = currentComboFormatIndex(ui.outputFormatCombo);
+ if (formatList[fidx].getOutputOptionsRef()->size() == 0) {
+ QMessageBox::information
+ (0, appName,
+ tr("There are no output options for format \"%1\"").arg(formatList[fidx].getDescription()));
+ }
+ else {
+ OptionsDlg optionDlg(0,
+ formatList[fidx].getName(),
+ formatList[fidx].getOutputOptionsRef(),
+ formatList[fidx].getHtml());
+ optionDlg.setWindowTitle(QString(appName) + " - " + tr("Options for %1").arg(formatList[fidx].getName()));
+ optionDlg.exec();
+ displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
+ }
+}
+
+
+
+//------------------------------------------------------------------------
+bool MainWindow::isOkToGo()
+{
+ if (!((ui.xlateWayPtsCk->isChecked() && ui.xlateWayPtsCk->isEnabled()) ||
+ (ui.xlateRoutesCk->isChecked() && ui.xlateRoutesCk->isEnabled()) ||
+ (ui.xlateTracksCk->isChecked() && ui.xlateTracksCk->isEnabled()))) {
+ QMessageBox::information(0, QString(appName), tr("No valid waypoints/routes/tracks translation specified"));
+ return false;
+ }
+
+ // Paper over what didn't happen in inputBrowse() if the user edited
+ // the filename fields directly.
+ if ((bd.inputType == BabelData::fileType) &&
+ (bd.inputFileNames.size() == 0) &&
+ (!ui.inputFileNameText->text().isEmpty())) {
+ bd.inputFileNames << ui.inputFileNameText->text();
+ }
+ if ((bd.outputType == BabelData::fileType) &&
+ (bd.outputFileName.size() == 0) &&
+ (!ui.outputFileNameText->text().isEmpty())) {
+ bd.outputFileName = ui.outputFileNameText->text();
+ }
+
+ if ((bd.inputType == BabelData::fileType) &&
+ (bd.inputFileNames.size() == 0)) {
+ QMessageBox::information(0, QString(appName), tr("No input file specified"));
+ return false;
+ }
+
+ if (bd.outputType == BabelData::noType && bd.previewGmap == true) {
+ }
+ if (bd.outputType == BabelData::noType && bd.previewGmap == false) {
+ QMessageBox::information(0, QString(appName), tr("No valid output specified"));
+ return false;
+ }
+ else if (bd.outputType == BabelData::fileType &&
+ bd.outputFileName.length() == 0) {
+ QMessageBox::information(0, QString(appName), tr("No output file specified"));
+ return false;
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------
+bool MainWindow::runGpsbabel(const QStringList &args, QString &errorString,
+ QString &outputString)
+{
+ QProcess *proc = new QProcess(0);
+ QString name = "gpsbabel";
+ proc->start(name, args);
+ ProcessWaitDialog *waitDlg = new ProcessWaitDialog(0, proc);
+
+ if (proc->state() == QProcess::NotRunning) {
+ errorString = QString(tr("Process \"%1\" did not start")).arg(name);
+ return false;
+ }
+
+ waitDlg->show();
+ waitDlg->exec();
+ int exitCode = -1;
+ bool retStatus = false;
+ if (waitDlg->getExitedNormally()) {
+ exitCode = waitDlg->getExitCode();
+ if (exitCode == 0)
+ retStatus = true;
+ else {
+ errorString =
+ QString(tr("Process exited unsucessfully with code %1"))
+ .arg(exitCode);
+ retStatus = false;
+ }
+ }
+ else {
+ retStatus = false;
+ errorString = waitDlg->getErrorString();
+ }
+ outputString = waitDlg->getOutputString();
+ delete proc;
+ delete waitDlg;
+ return retStatus;
+}
+
+//------------------------------------------------------------------------
+int MainWindow::formatIndexFromName(bool isFile, const QString &nm)
+{
+ for (int i= 0; i<formatList.size(); i++) {
+ if (nm == formatList[i].getName() && formatList[i].isFileFormat() == isFile)
+ return i;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+QString MainWindow::charSetFromCombo(QComboBox *combo)
+{
+ int i = combo->itemData((combo->currentIndex())).toInt();
+ return (i >=0 ) ? charSets[i] : QString();
+}
+
+//------------------------------------------------------------------------
+void MainWindow::setComboToCharSet(QComboBox *combo, const QString &cset)
+{
+ for (int i=0; i<charSets.size(); i++) {
+ if (charSets[i] == cset) {
+ combo->setCurrentIndex(i+1); // first index is default;
+ }
+ }
+}
+//------------------------------------------------------------------------
+void MainWindow::applyActionX()
+{
+ getWidgetValues();
+ if (!isOkToGo())
+ return;
+
+ QStringList args;
+
+ if (bd.debugLevel >=0) args << QString("-D%1").arg(bd.debugLevel);
+ if (bd.synthShortNames) args << "-s";
+
+ // Input char set if specified
+ if (bd.enableCharSetXform && bd.inputCharSet != QString())
+ args << "-c" << bd.inputCharSet;
+
+ Format ifmt = formatList[currentComboFormatIndex(ui.inputFormatCombo)];
+ Format ofmt = formatList[currentComboFormatIndex(ui.outputFormatCombo)];
+
+ if (bd.xlateWayPts && ifmt.isReadWaypoints() && ofmt.isWriteWaypoints())
+ args << "-w";
+ if (bd.xlateRoutes && ifmt.isReadRoutes() && ofmt.isWriteRoutes())
+ args << "-r";
+ if (bd.xlateTracks && ifmt.isReadTracks() && ofmt.isWriteTracks())
+ args << "-t";
+
+ // Input type, with options
+ bool iisFile = (bd.inputType == BabelData::fileType);
+ int fidx = formatIndexFromName(iisFile, iisFile ?
+ bd.inputFileFormat : bd.inputDeviceFormat);
+ args << "-i";
+ args << (formatList[fidx].getName() + MakeOptions(formatList[fidx].getInputOptions()));
+
+ // Input file(s) or device
+ int read_use_count = 0;
+ if (bd.inputType == BabelData::fileType) {
+ for (int i=0; i<bd.inputFileNames.size(); i++) {
+ args << "-f" << bd.inputFileNames[i];
+ read_use_count++;
+ }
+ }
+ else {
+ args << "-f" << bd.inputDeviceName;
+ read_use_count++;
+ }
+ formatList[fidx].bumpReadUseCount(read_use_count);
+
+ // --- Filters!
+ args << filterData.getAllFilterStrings();
+
+ // Output char set if specified
+ if (bd.enableCharSetXform && bd.outputCharSet != QString())
+ args << "-c" << bd.outputCharSet;
+
+ // Output type, with options
+ if (bd.outputType != BabelData::noType) {
+ bool outIsFile = (bd.outputType == BabelData::fileType);
+ fidx = formatIndexFromName(outIsFile, (outIsFile ?
+ bd.outputFileFormat : bd.outputDeviceFormat));
+ args << "-o";
+ args << (formatList[fidx].getName() + MakeOptions(formatList[fidx].getOutputOptions()));
+
+ // output file or device option
+ if (outIsFile) {
+ if (bd.outputFileName != "")
+ args << "-F" << bd.outputFileName;
+ }
+ else if (bd.outputType == BabelData::deviceType) {
+ args << "-F" << bd.outputDeviceName;
+ }
+ // GUI only ever writes a single file at a time.
+ formatList[fidx].bumpWriteUseCount(1);
+ }
+
+ // Now output for preview in google maps
+ QString tempName;
+ if (bd.previewGmap) {
+ QTemporaryFile ftemp;
+ ftemp.open();
+ tempName = ftemp.fileName();
+ ftemp.close();
+
+ // Ideally, expost this in the UI. For now, just split the track
+ // if we've no recorded fixes for > 5 mins and we've moved > 300 meters.
+ //args << "-x";
+ //args << "track,pack,sdistance=0.3k,split=5m";
+
+ args << "-o";
+ args << "gpx";
+ args << "-F" << tempName;
+ }
+
+ ui.outputWindow->clear();
+ ui.outputWindow->appendPlainText("gpsbabel " + args.join(" "));
+
+ QString errorString, outputString;
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ bool x = runGpsbabel(args, errorString, outputString);
+ QApplication::restoreOverrideCursor();
+
+ ui.outputWindow->appendPlainText(outputString);
+ if (x) {
+ ui.outputWindow->appendPlainText(tr("Translation successful"));
+ if (bd.previewGmap) {
+ this->hide();
+ GMapDialog dlg(0, tempName, bd.debugLevel >=1 ? ui.outputWindow : 0);
+ dlg.show();
+ dlg.exec();
+ this->show();
+ }
+ }
+ else
+ ui.outputWindow->appendPlainText(tr("Error running gpsbabel: %1\n").arg(errorString));
+}
+
+//------------------------------------------------------------------------
+void MainWindow::closeActionX()
+{
+ QDateTime wt= upgrade->getUpgradeWarningTime();
+ if (wt.isValid()) {
+ bd.upgradeCheckTime = wt;
+ }
+ bd.runCount++;
+
+ QDateTime now = QDateTime::currentDateTime();
+ if ((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) {
+ Donate donate(0);
+ if (bd.donateSplashed.date() == QDate(2010,1,1))
+ donate.showNever(false);
+ donate.exec();
+ bd.donateSplashed = now;
+ }
+ saveSettings();
+ delete upgrade;
+ upgrade = 0;
+ qApp->exit(0);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::closeEvent(QCloseEvent*)
+{
+ closeActionX();
+}
+
+//------------------------------------------------------------------------
+void MainWindow::donateActionX()
+{
+ QDesktopServices::openUrl(QString("http://www.gpsbabel.org/contribute.html?gbversion=" VERSION));
+}
+
+//------------------------------------------------------------------------
+void MainWindow::visitWebsiteActionX()
+{
+ QDesktopServices::openUrl(QString("http://www.gpsbabel.org"));
+}
+
+//------------------------------------------------------------------------
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ event->acceptProposedAction();
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ foreach (QString format, event->mimeData()->formats()) {
+ if (format == "text/uri-list") {
+ QList<QUrl> urlList = event->mimeData()->urls();
+ bd.inputFileNames.clear();
+ for (int i = 0; i < urlList.size(); ++i) {
+ QFileInfo file_info(urlList.at(i).path());
+ QString name = file_info.filePath();
+ QString ext = file_info.suffix();
+
+ QString fmt = getFormatNameForExtension(ext);
+ setComboToFormat(ui.inputFormatCombo, fmt, true);
+ ui.inputFileNameText->setText(name);
+ bd.inputFileNames << ui.inputFileNameText->text();
+ event->acceptProposedAction();
+ }
+ }
+ }
+}
+//------------------------------------------------------------------------
+void MainWindow::setComboToDevice(QComboBox *comboBox, const QString &name)
+{
+ for (int i=0; i<comboBox->count(); i++) {
+ if (comboBox->itemText(i) == name) {
+ comboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+void MainWindow::saveSettings()
+{
+ getWidgetValues();
+
+ QSettings settings;
+ bd.saveSettings(settings);
+ for (int i=0; i<formatList.size(); i++)
+ formatList[i].saveSettings(settings);
+ for (int i=0; i<filterData.filters.size(); i++)
+ filterData.filters[i]->saveSettings(settings);
+}
+
+//------------------------------------------------------------------------
+void MainWindow::restoreSettings()
+{
+ QSettings settings;
+ bd.restoreSettings(settings);
+ for (int i=0; i<formatList.size(); i++)
+ formatList[i].restoreSettings(settings);
+
+ for (int i=0; i<filterData.filters.size(); i++)
+ filterData.filters[i]->restoreSettings(settings);
+
+ setWidgetValues();
+}
+
+//------------------------------------------------------------------------
+void MainWindow::resetFormatDefaults()
+{
+ int ret = QMessageBox::warning
+ (this, QString(appName),
+ tr("Are you sure you want to reset all format options to default values?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (ret == QMessageBox::Yes) {
+ for (int i=0; i<formatList.size(); i++)
+ formatList[i].setToDefault();
+ displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
+ displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
+ }
+}
+
+//------------------------------------------------------------------------
+void MainWindow::moreOptionButtonClicked()
+{
+ AdvDlg advDlg(0, bd.synthShortNames,
+ bd.enableCharSetXform, bd.previewGmap, bd.debugLevel);
+ connect(advDlg.formatButton(), SIGNAL(clicked()),
+ this, SLOT(resetFormatDefaults()));
+ advDlg.exec();
+ checkCharSetCombos();
+}
+//------------------------------------------------------------------------
+void MainWindow::aboutActionX()
+{
+ AboutDlg aboutDlg(0, babelVersion, QString(appName) + QString(" " VERSION));
+ aboutDlg.setWindowTitle(tr("About %1").arg(appName));
+ aboutDlg.exec();
+}
+
+//------------------------------------------------------------------------
+void MainWindow::upgradeCheckActionX()
+{
+ upgrade->checkForUpgrade(babelVersion,
+ QDateTime(QDate(2000, 1, 1), QTime(0, 0)),
+ allowBetaUpgrades());
+}
+
+//------------------------------------------------------------------------
+void MainWindow::preferencesActionX()
+{
+ Preferences preferences(0, formatList, bd);
+ preferences.exec();
+
+ // We may have changed the list of displayed formats. Resynchronize.
+ setWidgetValues();
+}
+
+
+//------------------------------------------------------------------------
+void MainWindow::helpActionX()
+{
+ ShowHelp("index.html");
+}
+//------------------------------------------------------------------------
+void MainWindow::filtersClicked()
+{
+ FilterDialog dlg(0, filterData);
+ dlg.runDialog();
+ updateFilterStatus();
+}
+
+
+//------------------------------------------------------------------------
+void MainWindow::updateFilterStatus()
+{
+ bool filterActive = filterData.getAllFilterStrings().size();
+ ui.filterStatus->setEnabled(filterActive);
+ if (filterActive)
+ ui.filterStatus->setToolTip(tr("One or more data filters are active"));
+ else {
+ ui.filterStatus->setToolTip(tr("No data filters are active"));
+ }
+}
+//------------------------------------------------------------------------
+void MainWindow::setWidgetValues()
+{
+ if (bd.inputType == BabelData::fileType) {
+ ui.inputFileOptBtn->setChecked(true);
+ inputFileOptBtnClicked();
+ setComboToFormat(ui.inputFormatCombo, bd.inputFileFormat, true);
+ ui.inputStackedWidget->setCurrentWidget(ui.inputFilePage);
+ }
+ else {
+ ui.inputDeviceOptBtn->setChecked(true);
+ inputDeviceOptBtnClicked();
+ setComboToFormat(ui.inputFormatCombo, bd.inputDeviceFormat, false);
+ loadInputDeviceNameCombo(bd.inputDeviceFormat);
+ ui.inputStackedWidget->setCurrentWidget(ui.inputDevicePage);
+ }
+ setComboToDevice(ui.inputDeviceNameCombo, bd.inputDeviceName);
+ setComboToCharSet(ui.inputCharSetCombo, bd.inputCharSet);
+
+ if (bd.outputType == BabelData::fileType) {
+ ui.outputFileOptBtn->setChecked(true);
+ outputFileOptBtnClicked();
+ setComboToFormat(ui.outputFormatCombo, bd.outputFileFormat, true);
+ ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
+ }
+ else if (bd.outputType == BabelData::deviceType) {
+ ui.outputDeviceOptBtn->setChecked(true);
+ outputDeviceOptBtnClicked();
+ setComboToFormat(ui.outputFormatCombo, bd.outputDeviceFormat, false);
+ loadOutputDeviceNameCombo(bd.outputDeviceFormat);
+ ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
+ }
+ else {
+ ui.outputFileOptBtn->setChecked(false);
+ ui.outputDeviceOptBtn->setChecked(false);
+ setComboToFormat(ui.outputFormatCombo, bd.outputFileFormat, true);
+ ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
+ ui.outputFilePage->setDisabled(true);
+ }
+
+ setComboToDevice(ui.outputDeviceNameCombo, bd.outputDeviceName);
+ setComboToCharSet(ui.outputCharSetCombo, bd.outputCharSet);
+
+ ui.xlateWayPtsCk->setChecked(bd.xlateWayPts);
+ ui.xlateTracksCk->setChecked(bd.xlateTracks);
+ ui.xlateRoutesCk->setChecked(bd.xlateRoutes);
+
+ crossCheckInOutFormats();
+ displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
+ displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
+ checkCharSetCombos();
+ updateFilterStatus();
+}
+
+//------------------------------------------------------------------------
+void MainWindow::getWidgetValues()
+{
+ int comboIdx = ui.inputFormatCombo->currentIndex();
+ int fidx = ui.inputFormatCombo->itemData(comboIdx).toInt();
+ if (ui.inputFileOptBtn->isChecked()){
+ bd.inputType = BabelData::fileType;
+ bd.inputFileFormat =formatList[fidx].getName();
+ }
+ else {
+ bd.inputType = BabelData::deviceType;
+ bd.inputDeviceFormat =formatList[fidx].getName();
+ }
+ bd.inputDeviceName = ui.inputDeviceNameCombo->currentText();
+ bd.inputCharSet = charSetFromCombo(ui.inputCharSetCombo);
+
+ comboIdx = ui.outputFormatCombo->currentIndex();
+ fidx = ui.outputFormatCombo->itemData(comboIdx).toInt();
+ if (ui.outputFileOptBtn->isChecked()){
+ bd.outputType = BabelData::fileType;
+ bd.outputFileFormat =formatList[fidx].getName();
+ }
+ else if (ui.outputDeviceOptBtn->isChecked()){
+ bd.outputType = BabelData::deviceType;
+ bd.outputDeviceFormat =formatList[fidx].getName();
+ }
+ else {
+ bd.outputType = BabelData::noType;
+ }
+ bd.outputDeviceName = ui.outputDeviceNameCombo->currentText();
+ bd.outputCharSet = charSetFromCombo(ui.outputCharSetCombo);
+
+ bd.xlateWayPts = ui.xlateWayPtsCk->isChecked();
+ bd.xlateTracks = ui.xlateTracksCk->isChecked();
+ bd.xlateRoutes = ui.xlateRoutesCk->isChecked();
+}
+
+// This could be made faster, but any attempt to do so would have to be
+// careful about disabled formats. As it was written to be handled by a
+// drag response, performance is hardly critical.
+// It's also kind of dumb to return the name which SetCombo then looks up,
+// but there's not a 1:1 correlation between offsets in the combo box and
+// in the list of formats.
+QString MainWindow::getFormatNameForExtension(QString ext)
+{
+ for (int i = 0; i < formatList.size(); i++) {
+ QStringList extensions = formatList[i].getExtensions();
+ for (int j = 0; j < extensions.size(); ++j) {
+ if (extensions[j] == ext) {
+ return formatList[i].getName();;
+ }
+ }
+ }
+ return 0;
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: mainwindow.cpp,v 1.27 2010-11-01 03:30:42 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-#include <QDesktopServices>
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QMimeData>
-#include <QProcess>
-#include <QSettings>
-#include <QTemporaryFile>
-#include <QTextStream>
-
-#include "mainwindow.h"
-#include "../gbversion.h"
-#include "aboutdlg.h"
-#include "advdlg.h"
-#include "appname.h"
-#include "babeldata.h"
-#include "donate.h"
-#include "filterdlg.h"
-#include "formatload.h"
-#include "gmapdlg.h"
-#include "help.h"
-#include "optionsdlg.h"
-#include "preferences.h"
-#include "processwait.h"
-#include "version_mismatch.h"
-#include "upgrade.h"
-
-const int BabelData::noType = -1;
-const int BabelData::fileType = 0;
-const int BabelData::deviceType = 1;
-
-#define FAKE_LANGUAGE_MENU 0
-
-//------------------------------------------------------------------------
-QString MainWindow::findBabelVersion()
-{
- QProcess babel;
- babel.start("gpsbabel", QStringList() << "-V");
- if (!babel.waitForStarted())
- return QString();
- babel.closeWriteChannel();
- if (!babel.waitForFinished())
- return QString();
-
- QString str = babel.readAll();
- is_beta = str.contains("-beta");
- str.replace("Version", "");
- str.replace("GPSBabel", "");
- str.replace(QRegExp("^[\\s]*"), "");
- str.replace(QRegExp("[\\s]+$"), "");
- str = str.simplified();
- return str;
-}
-
-//------------------------------------------------------------------------
-// Decides whether available beta upgrades are suggested to user for download.
-bool MainWindow::allowBetaUpgrades()
-{
- // If this is a beta version (which means the user consciously downloaded
- // it and decided to be on the beta track or the user has ticked the
- // 'suggest beta upgrade' box, allow betas to be suggested for installation.
- return is_beta || bd.allowBetaUpgrades;
-}
-
-//------------------------------------------------------------------------
-static QStringList getCharSets()
-{
- QProcess babel;
- babel.start("gpsbabel", QStringList() << "-l");
- if (!babel.waitForStarted())
- return QStringList();
- babel.closeWriteChannel();
- if (!babel.waitForFinished())
- return QStringList();
-
- QStringList strList;
- QTextStream tstream(babel.readAll());
- while(!tstream.atEnd()) {
- QString l = tstream.readLine();
- if (QRegExp("^\\*").indexIn(l) == 0) {
- l.replace(QRegExp("^[\\*\\s]*"), "");
- l.replace(QRegExp("[\\s]+$"), "");
- strList << l;
- }
- }
- return strList;
-}
-
-//------------------------------------------------------------------------
-static QString MakeOptions(const QList<FormatOption>& options)
-{
- QString str;
- for (int i=0; i<options.size(); i++) {
- if (options[i].getSelected()) {
- str += ",";
- str += options[i].getName();
- if (options[i].getType() == FormatOption::OPTbool) {
- str += "=1";
- } else {
- str += "=" + options[i].getValue().toString();
- }
- } else {
- if (options[i].getType() == FormatOption::OPTbool) {
- str += "," + options[i].getName() + "=0";
- }
- }
- }
- return str;
-}
-
-//------------------------------------------------------------------------
-static QString MakeOptionsNoLeadingComma(const QList<FormatOption>& options)
-{
- QString str = MakeOptions(options);
- return (str.length()) ? str.mid(1) : str;
-
-}
-
-//------------------------------------------------------------------------
-MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
-{
- loadFormats();
- ui.setupUi(this);
- setWindowTitle(appName);
- babelVersion = findBabelVersion();
- fmtChgInterlock = false;
- loadDeviceNameCombos();
- loadCharSetCombos();
-
- connect(ui.inputFileOptBtn, SIGNAL(clicked()), this, SLOT(inputFileOptBtnClicked()));
- connect(ui.inputDeviceOptBtn, SIGNAL(clicked()), this, SLOT(inputDeviceOptBtnClicked()));
- connect(ui.inputFileNameBrowseBtn, SIGNAL(clicked()), this, SLOT(browseInputFile()));
-
- ui.outputFileOptBtn->setAutoExclusive(false);
- ui.outputDeviceOptBtn->setAutoExclusive(false);
- connect(ui.outputFileOptBtn, SIGNAL(clicked()), this, SLOT(outputFileOptBtnClicked()));
- connect(ui.outputDeviceOptBtn, SIGNAL(clicked()), this, SLOT(outputDeviceOptBtnClicked()));
- connect(ui.outputFileNameBrowseBtn, SIGNAL(clicked()), this, SLOT(browseOutputFile()));
-
- connect(ui.actionQuit, SIGNAL(triggered()), this, SLOT(closeActionX()));
- connect(ui.actionHelp, SIGNAL(triggered()), this, SLOT(helpActionX()));
- connect(ui.actionAbout, SIGNAL(triggered()), this, SLOT(aboutActionX()));
- connect(ui.actionVisit_Website, SIGNAL(triggered()), this, SLOT(visitWebsiteActionX()));
- connect(ui.actionMake_a_Donation, SIGNAL(triggered()), this, SLOT(donateActionX()));
- connect(ui.actionUpgradeCheck, SIGNAL(triggered()), this, SLOT(upgradeCheckActionX()));
- connect(ui.actionPreferences, SIGNAL(triggered()), this, SLOT(preferencesActionX()));
-
- connect(ui.inputFormatCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(inputFormatChanged(int)));
- connect(ui.outputFormatCombo, SIGNAL(currentIndexChanged(int)),
- this, SLOT(outputFormatChanged(int)));
- connect(ui.inputOptionsBtn, SIGNAL(clicked()),
- this, SLOT(inputOptionButtonClicked()));
- connect(ui.outputOptionsBtn , SIGNAL(clicked()),
- this, SLOT(outputOptionButtonClicked()));
- connect(ui.moreOptionButton , SIGNAL(clicked()),
- this, SLOT(moreOptionButtonClicked()));
-
- connect(ui.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(applyActionX()));
- connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(closeActionX()));
- connect(ui.xlateFiltersBtn, SIGNAL(clicked()), this, SLOT(filtersClicked()));
-
- connect(ui.inputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(inputFileNameEdited()));
- connect(ui.outputFileNameText, SIGNAL(textEdited(QString)), this, SLOT(outputFileNameEdited()));
-
-
- ui.buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon(":images/runit.png"));
- ui.buttonBox->button(QDialogButtonBox::Close)->setIcon(QIcon(":images/exit.png"));
-
-
- ui.inputOptionsText->setReadOnly(true);
- ui.outputOptionsText->setReadOnly(true);
-#if 0
- // 02/28/10 - let's try letting people edit these outside the browse.
- ui.inputFileNameText->setReadOnly(true);
- ui.outputFileNameText->setReadOnly(true);
-#else
- setAcceptDrops(true);
-#endif
- ui.wayPtLabel->setText("");
- ui.trackLabel->setText("");
- ui.routeLabel->setText("");
- lights[0] = QPixmap::fromImage(QImage(":images/00.png").scaledToHeight(20, Qt::SmoothTransformation));
- lights[1] = QPixmap::fromImage(QImage(":images/01.png").scaledToHeight(20, Qt::SmoothTransformation));
- lights[2] = QPixmap::fromImage(QImage(":images/10.png").scaledToHeight(20, Qt::SmoothTransformation));
- lights[3] = QPixmap::fromImage(QImage(":images/11.png").scaledToHeight(20, Qt::SmoothTransformation));
-
- ui.outputWindow->setReadOnly(true);
-
- langPath = QApplication::applicationDirPath();
- langPath.append("/translations/");
-
- // Start up in the current system language.
- loadLanguage(QLocale::system().name());
-#if FAKE_LANGUAGE_MENU
- createLanguageMenu();
-#endif
-
- //--- Restore from registry
- restoreSettings();
-
- upgrade = new UpgradeCheck(parent, formatList, bd);
- if (bd.startupVersionCheck) {
- upgrade->checkForUpgrade(babelVersion, bd.upgradeCheckTime,
- allowBetaUpgrades());
- }
-
- if (!bd.ignoreVersionMismatch && babelVersion != VERSION) {
- VersionMismatch vm(0, babelVersion, QString(VERSION));
-
- vm.exec();
- bd.ignoreVersionMismatch = vm.neverAgain();
- }
-}
-
-//------------------------------------------------------------------------
-MainWindow::~MainWindow()
-{
- if (upgrade)
- delete upgrade;
-}
-//------------------------------------------------------------------------
-// Dynamic language switching courtesy of
-// http://developer.qt.nokia.com/wiki/How_to_create_a_multi_language_application
-// We create the menu entries dynamically, dependant on the existing
-// translations.
-#if FAKE_LANGUAGE_MENU
-void MainWindow::createLanguageMenu(void)
-{
- QActionGroup* langGroup = new QActionGroup(ui.menuHelp);
- langGroup->setExclusive(true);
- connect(langGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotLanguageChanged(QAction *)));
-
- // format systems language
- QString defaultLocale = QLocale::system().name(); // e.g. "de_DE"
- defaultLocale.truncate(defaultLocale.lastIndexOf('_')); // e.g. "de"
-
- QDir dir(langPath);
- QStringList fileNames = dir.entryList(QStringList("GPSBabelFE*.qm"));
-
- for (int i = 0; i < fileNames.size(); ++i) {
- // get locale extracted by filename
- QString locale;
- locale = fileNames[i]; // "TranslationExample_de.qm"
- locale.truncate(locale.lastIndexOf('.')); // "TranslationExample_de"
- locale.remove(0, locale.indexOf('_') + 1); // "de"
-
- QString lang = QLocale::languageToString(QLocale(locale).language());
-
- QAction *action = new QAction(lang, this);
- action->setCheckable(true);
- action->setData(locale);
-
- ui.menuHelp->addAction(action);
- langGroup->addAction(action);
-
- // set default translators and language checked
- if (defaultLocale == locale) {
- action->setChecked(true);
- }
- }
-}
-#endif // FAKE_LANGUAGE_MENU
-
-//------------------------------------------------------------------------
-// Called every time, when a menu entry of the language menu is called
-void MainWindow::slotLanguageChanged(QAction* action)
-{
- if (0 != action) {
- // load the language dependant on the action content.
- loadLanguage(action->data().toString());
- }
-}
-
-void MainWindow::switchTranslator(QTranslator& translator, const QString& filename)
-{
- // remove the old translator
- qApp->removeTranslator(&translator);
-
- QString full_filename(langPath + "/" + filename);
-
- // load the new translator
- if (translator.load(full_filename))
- qApp->installTranslator(&translator);
-}
-
-void MainWindow::loadLanguage(const QString& rLanguage)
-{
- if (currLang != rLanguage) {
- currLang = rLanguage;
- QLocale locale = QLocale(currLang);
- QLocale::setDefault(locale);
- QString languageName = QLocale::languageToString(locale.language());
-
- switchTranslator(translator, QString("gpsbabelfe_%1.qm").arg(rLanguage));
- switchTranslator(translatorCore, QString("gpsbabel__%1.qm").arg(rLanguage));
- switchTranslator(translatorQt, QString("qt_%1.qm").arg(rLanguage));
- }
-}
-
-void MainWindow::changeEvent(QEvent* event)
-{
- if (0 != event) {
- switch(event->type()) {
- // This event is sent if a translator is loaded.
- case QEvent::LanguageChange:
- ui.retranslateUi(this);
- break;
- // This event is sent if the system language changes.
- case QEvent::LocaleChange:
- {
- QString locale = QLocale::system().name();
- locale.truncate(locale.lastIndexOf('_'));
- loadLanguage(locale);
- }
- break;
- default:
- break;
- }
- }
-
- QMainWindow::changeEvent(event);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::loadInputDeviceNameCombo(const QString &format)
-{
- ui.inputDeviceNameCombo->clear();
- // Later, we can probe the system for multiple USB devices and populate
- // here.
- if (formatSupportsUSB(format))
- ui.inputDeviceNameCombo->addItem("usb:");
- if (formatSupportsSerial(format))
- osLoadDeviceNameCombos(ui.inputDeviceNameCombo);
- // If only one choice, just disable it.
- ui.inputDeviceNameCombo->setEnabled(ui.inputDeviceNameCombo->count() > 1);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::loadOutputDeviceNameCombo(const QString &format)
-{
- ui.outputDeviceNameCombo->clear();
- // Later, we can probe the system for multiple USB devices and populate
- // here.
- if (formatSupportsUSB(format))
- ui.outputDeviceNameCombo->addItem("usb:");
- if (formatSupportsSerial(format))
- osLoadDeviceNameCombos(ui.outputDeviceNameCombo);
- // If only one choice, just disable it.
- ui.outputDeviceNameCombo->setEnabled(ui.outputDeviceNameCombo->count() > 1);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::loadDeviceNameCombos()
-{
- loadInputDeviceNameCombo("");
- loadOutputDeviceNameCombo("");
-}
-//------------------------------------------------------------------------
-void MainWindow::loadCharSetCombos()
-{
- charSets = getCharSets();
-
- ui.inputCharSetCombo->clear();
- ui.outputCharSetCombo->clear();
- ui.inputCharSetCombo->addItem(tr("default"), QVariant(-1));
- ui.outputCharSetCombo->addItem(tr("default"), QVariant(-1));
- for (int i=0; i<charSets.size(); i++) {
- ui.inputCharSetCombo->addItem(charSets[i], QVariant(i));
- ui.outputCharSetCombo->addItem(charSets[i], QVariant(i));
- }
-}
-//------------------------------------------------------------------------
-void MainWindow::checkCharSetCombos()
-{
- ui.inputCharSetCombo->setEnabled(bd.enableCharSetXform);
- ui.outputCharSetCombo->setEnabled(bd.enableCharSetXform);
- ui.inputCharSetCombo->setVisible(bd.enableCharSetXform);
- ui.outputCharSetCombo->setVisible(bd.enableCharSetXform);
-}
-//------------------------------------------------------------------------
-void MainWindow::inputFileOptBtnClicked()
-{
- fmtChgInterlock = true;
- QString fmt = bd.inputFileFormat;
- ui.inputStackedWidget->setCurrentWidget(ui.inputFilePage);
- QList<int>indices = inputFileFormatIndices();
- ui.inputFormatCombo->clear();
- for (int i=0; i<indices.size(); i++) {
- int k = indices[i];
- if (!formatList[k].isHidden())
- ui.inputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
- }
- setComboToFormat(ui.inputFormatCombo, fmt, true);
- fmtChgInterlock = false;
-}
-
-//------------------------------------------------------------------------
-void MainWindow::inputDeviceOptBtnClicked()
-{
- fmtChgInterlock = true;
- QString fmt = bd.inputDeviceFormat;
- ui.inputStackedWidget->setCurrentWidget(ui.inputDevicePage);
- QList<int>indices = inputDeviceFormatIndices();
- ui.inputFormatCombo->clear();
- for (int i=0; i<indices.size(); i++) {
- int k = indices[i];
- if (!formatList[k].isHidden())
- ui.inputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
- }
- setComboToFormat(ui.inputFormatCombo, fmt, false);
- fmtChgInterlock = false;
-}
-
-//------------------------------------------------------------------------
-void MainWindow:: outputFileOptBtnClicked()
-{
- fmtChgInterlock = true;
- if (ui.outputFileOptBtn->isChecked()) {
- ui.outputFilePage->setEnabled(true);
- ui.outputDeviceOptBtn->setChecked(false);
- QString fmt = bd.outputFileFormat;
- ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
- QList<int>indices = outputFileFormatIndices();
- ui.outputFormatCombo->clear();
- for (int i=0; i<indices.size(); i++) {
- int k = indices[i];
- ui.outputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
- }
- setComboToFormat(ui.outputFormatCombo, fmt, true);
- }
- else {
- ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
- ui.outputFilePage->setEnabled(false);
- }
- fmtChgInterlock = false;
-}
-
-//------------------------------------------------------------------------
-void MainWindow:: outputDeviceOptBtnClicked()
-{
- fmtChgInterlock = true;
- if (ui.outputDeviceOptBtn->isChecked()) {
- ui.outputDevicePage->setEnabled(true);
- ui.outputFileOptBtn->setChecked(false);
- QString fmt = bd.outputDeviceFormat;
- ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
- QList<int>indices = outputDeviceFormatIndices();
- ui.outputFormatCombo->clear();
- for (int i=0; i<indices.size(); i++) {
- int k = indices[i];
- ui.outputFormatCombo->addItem(formatList[k].getDescription(), QVariant(k));
- }
- setComboToFormat(ui.outputFormatCombo, fmt, false);
- }
- else {
- ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
- ui.outputDevicePage->setEnabled(false);
- }
- fmtChgInterlock = false;
-}
-void MainWindow::inputFileNameEdited()
-{
- bd.inputFileNames.clear();
- bd.inputFileNames << ui.inputFileNameText->text();
-}
-
-void MainWindow::outputFileNameEdited()
-{
- bd.outputFileName = ui.outputFileNameText->text();
-
-}
-
-//------------------------------------------------------------------------
-QString MainWindow::filterForFormat(int idx)
-{
- QString str = formatList[idx].getDescription();
- str.replace(QRegExp("\\("), "[");
- str.replace(QRegExp("\\)"), "]");
- QStringList extensions = formatList[idx].getExtensions();
-
- // If we don't have any meaningful extensions available for this format,
- // don't be clever here; just fall through to "All files" case.
- if (extensions.size() > 0 && !extensions[0].isEmpty()) {
- str += " (";
- for (int i=0; i<extensions.size(); i++) {
- if (i!= 0)
- str += " ";
- str += "*." + extensions[i];
- }
- str += ");;";
- }
- str += "All Files (*.*)";
- return str;
-}
-//------------------------------------------------------------------------
-QString MainWindow::ensureExtensionPresent(const QString &name, int idx)
-{
- QString outname = name;
- if (QFileInfo(name).suffix().length() == 0) {
- QStringList extensions = formatList[idx].getExtensions();
- if (extensions.size() > 0)
- outname += "." + extensions[0];
- }
- return outname;
-}
-
-//------------------------------------------------------------------------
-bool MainWindow::filterForFormatIncludes(int idx, const QString &fmt)
-{
- QStringList extensions = formatList[idx].getExtensions();
- for (int i=0; i<extensions.size(); i++) {
- if (fmt == extensions[i])
- return true;
- }
- return false;
-}
-
-//------------------------------------------------------------------------
-int MainWindow::currentComboFormatIndex(QComboBox *comboBox)
-{
- int idx = comboBox->currentIndex();
- if (idx<0 || idx >= comboBox->count()) {
- // QMessageBox::critical(0, appName, "*** Internal Error -- current combo index is invalid!");
- return 0;
- }
- return comboBox->itemData(idx).toInt();
-}
-//------------------------------------------------------------------------
-void MainWindow::browseInputFile()
-{
- QString startFile = bd.inputFileNames.size() ? bd.inputFileNames[0] : bd.inputBrowse;
- int idx = currentComboFormatIndex(ui.inputFormatCombo);
- QFileInfo finfo(startFile);
- if (!finfo.isDir() && (!filterForFormatIncludes(idx, finfo.suffix()))) {
- startFile = finfo.dir().absolutePath();
- }
-
- QStringList userList =
- QFileDialog::getOpenFileNames(0, tr("Select one or more input files"),
- startFile,
- filterForFormat(idx));
- if (userList.size()) {
- bd.inputBrowse = userList[0];
- bd.inputFileNames = userList;
- QString str;
- for (int i=0; i<bd.inputFileNames.size(); i++) {
- if (i != 0)
- str += ", ";
- str += "\"" + bd.inputFileNames[i] + "\"";
- }
- ui.inputFileNameText->setText(str);
- }
-}
-
-//------------------------------------------------------------------------
-void MainWindow::browseOutputFile()
-{
- int idx = currentComboFormatIndex(ui.outputFormatCombo);
- QString startFile = bd.outputFileName.length() == 0 ? bd.outputBrowse : bd.outputFileName;
- QFileInfo finfo(startFile);
- if (!finfo.isDir() && (!filterForFormatIncludes(idx, finfo.suffix()))) {
- startFile = finfo.dir().absolutePath();
- }
-
- QString str =
- QFileDialog::getSaveFileName(0, tr("Output File Name"),
- startFile,
- filterForFormat(idx));
- if (str.length() != 0) {
- str = ensureExtensionPresent(str, idx);
- bd.outputBrowse = str;
- bd.outputFileName = str;
- ui.outputFileNameText->setText(str);
- }
-}
-
-//------------------------------------------------------------------------
-QList<int> MainWindow::inputFileFormatIndices()
-{
- QList<int>indices;
- for (int i=0; i<formatList.size(); i++) {
- if (formatList[i].isReadSomething() && formatList[i].isFileFormat())
- indices<<i;
- }
- return indices;
-}
-
-//------------------------------------------------------------------------
-QList<int> MainWindow::inputDeviceFormatIndices()
-{
- QList<int>indices;
- for (int i=0; i<formatList.size(); i++) {
- if (formatList[i].isReadSomething() && formatList[i].isDeviceFormat())
- indices<<i;
- }
- return indices;
-}
-
-//------------------------------------------------------------------------
-QList<int> MainWindow::outputFileFormatIndices()
-{
- QList<int>indices;
- for (int i=0; i<formatList.size(); i++) {
- if (formatList[i].isWriteSomething() && formatList[i].isFileFormat())
- indices<<i;
- }
- return indices;
-}
-
-//------------------------------------------------------------------------
-QList<int> MainWindow::outputDeviceFormatIndices()
-{
- QList<int>indices;
- for (int i=0; i<formatList.size(); i++) {
- if (formatList[i].isWriteSomething() && formatList[i].isDeviceFormat())
- indices<<i;
- }
- return indices;
-}
-
-//------------------------------------------------------------------------
-void MainWindow::loadFormats()
-{
- if (!FormatLoad().getFormats(formatList)) {
- QMessageBox::information(0, QString(appName),
- tr("Error reading format configuration. "
- "Check that the backend program \"gpsbabel\" is properly installed "
- "and is in the current PATH\n\n"
- "This program cannot continue."));
- exit(1);
- }
- if (inputFileFormatIndices().size() == 0 ||
- inputDeviceFormatIndices().size() == 0 ||
- outputFileFormatIndices().size() == 0 ||
- outputDeviceFormatIndices().size() == 0) {
- QMessageBox::information(0, QString(appName),
- tr("Some file/device formats were not found during initialization. "
- "Check that the backend program \"gpsbabel\" is properly installed "
- "and is in the current PATH\n\n"
- "This program cannot continue."));
- exit(1);
- }
-}
-//------------------------------------------------------------------------
-static int iconIndex(bool a, bool b)
-{
- return ((a?1:0)*2) + (b?1:0);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::setIndicatorLights(QLabel *label, const QString &type, int code)
-{
- label->setPixmap(lights[code]);
- QString s;
- switch (code)
- {
- default:
- case 0:
- s = tr("Input and output formats do not support %1").arg(type);
- break;
- case 1:
- s = tr("Input does not support %1; output format supports %2").arg(type).arg(type);
- break;
- case 2:
- s = tr("Input format supports %1; output format does not support %2").arg(type).arg(type);
- break;
- case 3:
- s = tr("Both input and output formats support %1").arg(type);
- break;
- }
- label->setToolTip(s);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::crossCheckInOutFormats()
-{
- if (ui.inputFormatCombo->count() == 0 ||
- ui.outputFormatCombo->count() == 0) {
- // During format/device switch this is true
- return;
- }
- Format ifmt = formatList[currentComboFormatIndex(ui.inputFormatCombo)];
- Format ofmt = formatList[currentComboFormatIndex(ui.outputFormatCombo)];
-
- ui.xlateWayPtsCk->setEnabled(ifmt.isReadWaypoints() && ofmt.isWriteWaypoints());
- ui.xlateTracksCk->setEnabled(ifmt.isReadTracks() && ofmt.isWriteTracks());
- ui.xlateRoutesCk->setEnabled(ifmt.isReadRoutes() && ofmt.isWriteRoutes());
-
- setIndicatorLights(ui.wayPtLabel, tr("waypoints"), iconIndex(ifmt.isReadWaypoints(), ofmt.isWriteWaypoints()));
- setIndicatorLights(ui.trackLabel, tr("tracks"), iconIndex(ifmt.isReadTracks(), ofmt.isWriteTracks()));
- setIndicatorLights(ui.routeLabel, tr("routes"), iconIndex(ifmt.isReadRoutes(), ofmt.isWriteRoutes()));
-}
-
-//------------------------------------------------------------------------
-void MainWindow::displayOptionsText(QLineEdit *le, QComboBox *combo, bool isInput)
-{
- int fidx = combo->itemData(combo->currentIndex()).toInt();
- if (isInput)
- le->setText(MakeOptionsNoLeadingComma(formatList[fidx].getInputOptions()));
- else
- le->setText(MakeOptionsNoLeadingComma(formatList[fidx].getOutputOptions()));
-
-}
-
-//------------------------------------------------------------------------
-void MainWindow::setComboToFormat(QComboBox *comboBox, const QString &name, bool isFile)
-{
- int fidx = -1;
- for (int i=0; i<formatList.size(); i++) {
- if (formatList[i].getName() == name &&
- formatList[i].isFileFormat() == isFile) {
- fidx = i;
- break;
- }
- }
- if (fidx >=0) {
- for (int i=0; i<comboBox->count(); i++) {
- if (comboBox->itemData(i).toInt() == fidx) {
- comboBox->setCurrentIndex(i);
- break;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------
-bool MainWindow::formatSupportsUSB(const QString &format)
-{
- return (format == "garmin" || format == "delbin");
-}
-
-//------------------------------------------------------------------------
-bool MainWindow::formatSupportsSerial(const QString &format)
-{
- return (format != "delbin");
-}
-
-//------------------------------------------------------------------------
-void MainWindow::inputFormatChanged(int comboIdx)
-{
- if (fmtChgInterlock)
- return;
- int fidx = ui.inputFormatCombo->itemData(comboIdx).toInt();
- ui.inputOptionsBtn->setEnabled(formatList[fidx].getInputOptions().size()>0);
- displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
- crossCheckInOutFormats();
-
- if (ui.inputFileOptBtn->isChecked())
- bd.inputFileFormat =formatList[fidx].getName();
- else
- bd.inputDeviceFormat = formatList[fidx].getName();
-
- loadInputDeviceNameCombo(formatList[fidx].getName());
-}
-
-//------------------------------------------------------------------------
-void MainWindow::outputFormatChanged(int comboIdx)
-{
- if (fmtChgInterlock)
- return;
- int fidx = ui.outputFormatCombo->itemData(comboIdx).toInt();
- ui.outputOptionsBtn->setEnabled(formatList[fidx].getOutputOptions().size()>0);
- displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
- crossCheckInOutFormats();
-
- if (ui.outputFileOptBtn->isChecked())
- bd.outputFileFormat =formatList[fidx].getName();
- else if (ui.outputDeviceOptBtn->isChecked())
- bd.outputDeviceFormat = formatList[fidx].getName();
-
- loadOutputDeviceNameCombo(formatList[fidx].getName());
-}
-
-//------------------------------------------------------------------------
-void MainWindow::inputOptionButtonClicked()
-{
- int fidx = currentComboFormatIndex(ui.inputFormatCombo);
- if (formatList[fidx].getInputOptionsRef()->size() == 0) {
- QMessageBox::information
- (0, appName,
- tr("There are no input options for format \"%1\"").arg(formatList[fidx].getDescription()));
- }
- else {
- OptionsDlg optionDlg(0,
- formatList[fidx].getName(),
- formatList[fidx].getInputOptionsRef(),
- formatList[fidx].getHtml());
- optionDlg.setWindowTitle(QString(appName) + " - " + tr("Options for %1").arg(formatList[fidx].getName()));
- optionDlg.exec();
- displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
- }
-}
-
-//------------------------------------------------------------------------
-void MainWindow::outputOptionButtonClicked()
-{
- int fidx = currentComboFormatIndex(ui.outputFormatCombo);
- if (formatList[fidx].getOutputOptionsRef()->size() == 0) {
- QMessageBox::information
- (0, appName,
- tr("There are no output options for format \"%1\"").arg(formatList[fidx].getDescription()));
- }
- else {
- OptionsDlg optionDlg(0,
- formatList[fidx].getName(),
- formatList[fidx].getOutputOptionsRef(),
- formatList[fidx].getHtml());
- optionDlg.setWindowTitle(QString(appName) + " - " + tr("Options for %1").arg(formatList[fidx].getName()));
- optionDlg.exec();
- displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
- }
-}
-
-
-
-//------------------------------------------------------------------------
-bool MainWindow::isOkToGo()
-{
- if (!((ui.xlateWayPtsCk->isChecked() && ui.xlateWayPtsCk->isEnabled()) ||
- (ui.xlateRoutesCk->isChecked() && ui.xlateRoutesCk->isEnabled()) ||
- (ui.xlateTracksCk->isChecked() && ui.xlateTracksCk->isEnabled()))) {
- QMessageBox::information(0, QString(appName), tr("No valid waypoints/routes/tracks translation specified"));
- return false;
- }
-
- // Paper over what didn't happen in inputBrowse() if the user edited
- // the filename fields directly.
- if ((bd.inputType == BabelData::fileType) &&
- (bd.inputFileNames.size() == 0) &&
- (!ui.inputFileNameText->text().isEmpty())) {
- bd.inputFileNames << ui.inputFileNameText->text();
- }
- if ((bd.outputType == BabelData::fileType) &&
- (bd.outputFileName.size() == 0) &&
- (!ui.outputFileNameText->text().isEmpty())) {
- bd.outputFileName = ui.outputFileNameText->text();
- }
-
- if ((bd.inputType == BabelData::fileType) &&
- (bd.inputFileNames.size() == 0)) {
- QMessageBox::information(0, QString(appName), tr("No input file specified"));
- return false;
- }
-
- if (bd.outputType == BabelData::noType && bd.previewGmap == true) {
- }
- if (bd.outputType == BabelData::noType && bd.previewGmap == false) {
- QMessageBox::information(0, QString(appName), tr("No valid output specified"));
- return false;
- }
- else if (bd.outputType == BabelData::fileType &&
- bd.outputFileName.length() == 0) {
- QMessageBox::information(0, QString(appName), tr("No output file specified"));
- return false;
- }
- return true;
-}
-
-//------------------------------------------------------------------------
-bool MainWindow::runGpsbabel(const QStringList &args, QString &errorString,
- QString &outputString)
-{
- QProcess *proc = new QProcess(0);
- QString name = "gpsbabel";
- proc->start(name, args);
- ProcessWaitDialog *waitDlg = new ProcessWaitDialog(0, proc);
-
- if (proc->state() == QProcess::NotRunning) {
- errorString = QString(tr("Process \"%1\" did not start")).arg(name);
- return false;
- }
-
- waitDlg->show();
- waitDlg->exec();
- int exitCode = -1;
- bool retStatus = false;
- if (waitDlg->getExitedNormally()) {
- exitCode = waitDlg->getExitCode();
- if (exitCode == 0)
- retStatus = true;
- else {
- errorString =
- QString(tr("Process exited unsucessfully with code %1"))
- .arg(exitCode);
- retStatus = false;
- }
- }
- else {
- retStatus = false;
- errorString = waitDlg->getErrorString();
- }
- outputString = waitDlg->getOutputString();
- delete proc;
- delete waitDlg;
- return retStatus;
-}
-
-//------------------------------------------------------------------------
-int MainWindow::formatIndexFromName(bool isFile, const QString &nm)
-{
- for (int i= 0; i<formatList.size(); i++) {
- if (nm == formatList[i].getName() && formatList[i].isFileFormat() == isFile)
- return i;
- }
- return 0;
-}
-
-//------------------------------------------------------------------------
-QString MainWindow::charSetFromCombo(QComboBox *combo)
-{
- int i = combo->itemData((combo->currentIndex())).toInt();
- return (i >=0 ) ? charSets[i] : QString();
-}
-
-//------------------------------------------------------------------------
-void MainWindow::setComboToCharSet(QComboBox *combo, const QString &cset)
-{
- for (int i=0; i<charSets.size(); i++) {
- if (charSets[i] == cset) {
- combo->setCurrentIndex(i+1); // first index is default;
- }
- }
-}
-//------------------------------------------------------------------------
-void MainWindow::applyActionX()
-{
- getWidgetValues();
- if (!isOkToGo())
- return;
-
- QStringList args;
-
- if (bd.debugLevel >=0) args << QString("-D%1").arg(bd.debugLevel);
- if (bd.synthShortNames) args << "-s";
-
- // Input char set if specified
- if (bd.enableCharSetXform && bd.inputCharSet != QString())
- args << "-c" << bd.inputCharSet;
-
- Format ifmt = formatList[currentComboFormatIndex(ui.inputFormatCombo)];
- Format ofmt = formatList[currentComboFormatIndex(ui.outputFormatCombo)];
-
- if (bd.xlateWayPts && ifmt.isReadWaypoints() && ofmt.isWriteWaypoints())
- args << "-w";
- if (bd.xlateRoutes && ifmt.isReadRoutes() && ofmt.isWriteRoutes())
- args << "-r";
- if (bd.xlateTracks && ifmt.isReadTracks() && ofmt.isWriteTracks())
- args << "-t";
-
- // Input type, with options
- bool iisFile = (bd.inputType == BabelData::fileType);
- int fidx = formatIndexFromName(iisFile, iisFile ?
- bd.inputFileFormat : bd.inputDeviceFormat);
- args << "-i";
- args << (formatList[fidx].getName() + MakeOptions(formatList[fidx].getInputOptions()));
-
- // Input file(s) or device
- int read_use_count = 0;
- if (bd.inputType == BabelData::fileType) {
- for (int i=0; i<bd.inputFileNames.size(); i++) {
- args << "-f" << bd.inputFileNames[i];
- read_use_count++;
- }
- }
- else {
- args << "-f" << bd.inputDeviceName;
- read_use_count++;
- }
- formatList[fidx].bumpReadUseCount(read_use_count);
-
- // --- Filters!
- args << filterData.getAllFilterStrings();
-
- // Output char set if specified
- if (bd.enableCharSetXform && bd.outputCharSet != QString())
- args << "-c" << bd.outputCharSet;
-
- // Output type, with options
- if (bd.outputType != BabelData::noType) {
- bool outIsFile = (bd.outputType == BabelData::fileType);
- fidx = formatIndexFromName(outIsFile, (outIsFile ?
- bd.outputFileFormat : bd.outputDeviceFormat));
- args << "-o";
- args << (formatList[fidx].getName() + MakeOptions(formatList[fidx].getOutputOptions()));
-
- // output file or device option
- if (outIsFile) {
- if (bd.outputFileName != "")
- args << "-F" << bd.outputFileName;
- }
- else if (bd.outputType == BabelData::deviceType) {
- args << "-F" << bd.outputDeviceName;
- }
- // GUI only ever writes a single file at a time.
- formatList[fidx].bumpWriteUseCount(1);
- }
-
- // Now output for preview in google maps
- QString tempName;
- if (bd.previewGmap) {
- QTemporaryFile ftemp;
- ftemp.open();
- tempName = ftemp.fileName();
- ftemp.close();
-
- // Ideally, expost this in the UI. For now, just split the track
- // if we've no recorded fixes for > 5 mins and we've moved > 300 meters.
- //args << "-x";
- //args << "track,pack,sdistance=0.3k,split=5m";
-
- args << "-o";
- args << "gpx";
- args << "-F" << tempName;
- }
-
- ui.outputWindow->clear();
- ui.outputWindow->appendPlainText("gpsbabel " + args.join(" "));
-
- QString errorString, outputString;
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- bool x = runGpsbabel(args, errorString, outputString);
- QApplication::restoreOverrideCursor();
-
- ui.outputWindow->appendPlainText(outputString);
- if (x) {
- ui.outputWindow->appendPlainText(tr("Translation successful"));
- if (bd.previewGmap) {
- this->hide();
- GMapDialog dlg(0, tempName, bd.debugLevel >=1 ? ui.outputWindow : 0);
- dlg.show();
- dlg.exec();
- this->show();
- }
- }
- else
- ui.outputWindow->appendPlainText(tr("Error running gpsbabel: %1\n").arg(errorString));
-}
-
-//------------------------------------------------------------------------
-void MainWindow::closeActionX()
-{
- QDateTime wt= upgrade->getUpgradeWarningTime();
- if (wt.isValid()) {
- bd.upgradeCheckTime = wt;
- }
- bd.runCount++;
-
- QDateTime now = QDateTime::currentDateTime();
- if ((bd.runCount > 5) && (bd.donateSplashed.daysTo(now) > 30)) {
- Donate donate(0);
- if (bd.donateSplashed.date() == QDate(2010,1,1))
- donate.showNever(false);
- donate.exec();
- bd.donateSplashed = now;
- }
- saveSettings();
- delete upgrade;
- upgrade = 0;
- qApp->exit(0);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::closeEvent(QCloseEvent*)
-{
- closeActionX();
-}
-
-//------------------------------------------------------------------------
-void MainWindow::donateActionX()
-{
- QDesktopServices::openUrl(QString("http://www.gpsbabel.org/contribute.html?gbversion=" VERSION));
-}
-
-//------------------------------------------------------------------------
-void MainWindow::visitWebsiteActionX()
-{
- QDesktopServices::openUrl(QString("http://www.gpsbabel.org"));
-}
-
-//------------------------------------------------------------------------
-void MainWindow::dragEnterEvent(QDragEnterEvent *event)
-{
- event->acceptProposedAction();
-}
-
-void MainWindow::dropEvent(QDropEvent *event)
-{
- foreach (QString format, event->mimeData()->formats()) {
- if (format == "text/uri-list") {
- QList<QUrl> urlList = event->mimeData()->urls();
- bd.inputFileNames.clear();
- for (int i = 0; i < urlList.size(); ++i) {
- QFileInfo file_info(urlList.at(i).path());
- QString name = file_info.filePath();
- QString ext = file_info.suffix();
-
- QString fmt = getFormatNameForExtension(ext);
- setComboToFormat(ui.inputFormatCombo, fmt, true);
- ui.inputFileNameText->setText(name);
- bd.inputFileNames << ui.inputFileNameText->text();
- event->acceptProposedAction();
- }
- }
- }
-}
-//------------------------------------------------------------------------
-void MainWindow::setComboToDevice(QComboBox *comboBox, const QString &name)
-{
- for (int i=0; i<comboBox->count(); i++) {
- if (comboBox->itemText(i) == name) {
- comboBox->setCurrentIndex(i);
- break;
- }
- }
-}
-
-//------------------------------------------------------------------------
-void MainWindow::saveSettings()
-{
- getWidgetValues();
-
- QSettings settings;
- bd.saveSettings(settings);
- for (int i=0; i<formatList.size(); i++)
- formatList[i].saveSettings(settings);
- for (int i=0; i<filterData.filters.size(); i++)
- filterData.filters[i]->saveSettings(settings);
-}
-
-//------------------------------------------------------------------------
-void MainWindow::restoreSettings()
-{
- QSettings settings;
- bd.restoreSettings(settings);
- for (int i=0; i<formatList.size(); i++)
- formatList[i].restoreSettings(settings);
-
- for (int i=0; i<filterData.filters.size(); i++)
- filterData.filters[i]->restoreSettings(settings);
-
- setWidgetValues();
-}
-
-//------------------------------------------------------------------------
-void MainWindow::resetFormatDefaults()
-{
- int ret = QMessageBox::warning
- (this, QString(appName),
- tr("Are you sure you want to reset all format options to default values?"),
- QMessageBox::Yes | QMessageBox::No);
- if (ret == QMessageBox::Yes) {
- for (int i=0; i<formatList.size(); i++)
- formatList[i].setToDefault();
- displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
- displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
- }
-}
-
-//------------------------------------------------------------------------
-void MainWindow::moreOptionButtonClicked()
-{
- AdvDlg advDlg(0, bd.synthShortNames,
- bd.enableCharSetXform, bd.previewGmap, bd.debugLevel);
- connect(advDlg.formatButton(), SIGNAL(clicked()),
- this, SLOT(resetFormatDefaults()));
- advDlg.exec();
- checkCharSetCombos();
-}
-//------------------------------------------------------------------------
-void MainWindow::aboutActionX()
-{
- AboutDlg aboutDlg(0, babelVersion, QString(appName) + QString(" " VERSION));
- aboutDlg.setWindowTitle(tr("About %1").arg(appName));
- aboutDlg.exec();
-}
-
-//------------------------------------------------------------------------
-void MainWindow::upgradeCheckActionX()
-{
- upgrade->checkForUpgrade(babelVersion,
- QDateTime(QDate(2000, 1, 1), QTime(0, 0)),
- allowBetaUpgrades());
-}
-
-//------------------------------------------------------------------------
-void MainWindow::preferencesActionX()
-{
- Preferences preferences(0, formatList, bd);
- preferences.exec();
-
- // We may have changed the list of displayed formats. Resynchronize.
- setWidgetValues();
-}
-
-
-//------------------------------------------------------------------------
-void MainWindow::helpActionX()
-{
- ShowHelp("index.html");
-}
-//------------------------------------------------------------------------
-void MainWindow::filtersClicked()
-{
- FilterDialog dlg(0, filterData);
- dlg.runDialog();
- updateFilterStatus();
-}
-
-
-//------------------------------------------------------------------------
-void MainWindow::updateFilterStatus()
-{
- bool filterActive = filterData.getAllFilterStrings().size();
- ui.filterStatus->setEnabled(filterActive);
- if (filterActive)
- ui.filterStatus->setToolTip(tr("One or more data filters are active"));
- else {
- ui.filterStatus->setToolTip(tr("No data filters are active"));
- }
-}
-//------------------------------------------------------------------------
-void MainWindow::setWidgetValues()
-{
- if (bd.inputType == BabelData::fileType) {
- ui.inputFileOptBtn->setChecked(true);
- inputFileOptBtnClicked();
- setComboToFormat(ui.inputFormatCombo, bd.inputFileFormat, true);
- ui.inputStackedWidget->setCurrentWidget(ui.inputFilePage);
- }
- else {
- ui.inputDeviceOptBtn->setChecked(true);
- inputDeviceOptBtnClicked();
- setComboToFormat(ui.inputFormatCombo, bd.inputDeviceFormat, false);
- loadInputDeviceNameCombo(bd.inputDeviceFormat);
- ui.inputStackedWidget->setCurrentWidget(ui.inputDevicePage);
- }
- setComboToDevice(ui.inputDeviceNameCombo, bd.inputDeviceName);
- setComboToCharSet(ui.inputCharSetCombo, bd.inputCharSet);
-
- if (bd.outputType == BabelData::fileType) {
- ui.outputFileOptBtn->setChecked(true);
- outputFileOptBtnClicked();
- setComboToFormat(ui.outputFormatCombo, bd.outputFileFormat, true);
- ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
- }
- else if (bd.outputType == BabelData::deviceType) {
- ui.outputDeviceOptBtn->setChecked(true);
- outputDeviceOptBtnClicked();
- setComboToFormat(ui.outputFormatCombo, bd.outputDeviceFormat, false);
- loadOutputDeviceNameCombo(bd.outputDeviceFormat);
- ui.outputStackedWidget->setCurrentWidget(ui.outputDevicePage);
- }
- else {
- ui.outputFileOptBtn->setChecked(false);
- ui.outputDeviceOptBtn->setChecked(false);
- setComboToFormat(ui.outputFormatCombo, bd.outputFileFormat, true);
- ui.outputStackedWidget->setCurrentWidget(ui.outputFilePage);
- ui.outputFilePage->setDisabled(true);
- }
-
- setComboToDevice(ui.outputDeviceNameCombo, bd.outputDeviceName);
- setComboToCharSet(ui.outputCharSetCombo, bd.outputCharSet);
-
- ui.xlateWayPtsCk->setChecked(bd.xlateWayPts);
- ui.xlateTracksCk->setChecked(bd.xlateTracks);
- ui.xlateRoutesCk->setChecked(bd.xlateRoutes);
-
- crossCheckInOutFormats();
- displayOptionsText(ui.inputOptionsText, ui.inputFormatCombo, true);
- displayOptionsText(ui.outputOptionsText, ui.outputFormatCombo, false);
- checkCharSetCombos();
- updateFilterStatus();
-}
-
-//------------------------------------------------------------------------
-void MainWindow::getWidgetValues()
-{
- int comboIdx = ui.inputFormatCombo->currentIndex();
- int fidx = ui.inputFormatCombo->itemData(comboIdx).toInt();
- if (ui.inputFileOptBtn->isChecked()){
- bd.inputType = BabelData::fileType;
- bd.inputFileFormat =formatList[fidx].getName();
- }
- else {
- bd.inputType = BabelData::deviceType;
- bd.inputDeviceFormat =formatList[fidx].getName();
- }
- bd.inputDeviceName = ui.inputDeviceNameCombo->currentText();
- bd.inputCharSet = charSetFromCombo(ui.inputCharSetCombo);
-
- comboIdx = ui.outputFormatCombo->currentIndex();
- fidx = ui.outputFormatCombo->itemData(comboIdx).toInt();
- if (ui.outputFileOptBtn->isChecked()){
- bd.outputType = BabelData::fileType;
- bd.outputFileFormat =formatList[fidx].getName();
- }
- else if (ui.outputDeviceOptBtn->isChecked()){
- bd.outputType = BabelData::deviceType;
- bd.outputDeviceFormat =formatList[fidx].getName();
- }
- else {
- bd.outputType = BabelData::noType;
- }
- bd.outputDeviceName = ui.outputDeviceNameCombo->currentText();
- bd.outputCharSet = charSetFromCombo(ui.outputCharSetCombo);
-
- bd.xlateWayPts = ui.xlateWayPtsCk->isChecked();
- bd.xlateTracks = ui.xlateTracksCk->isChecked();
- bd.xlateRoutes = ui.xlateRoutesCk->isChecked();
-}
-
-// This could be made faster, but any attempt to do so would have to be
-// careful about disabled formats. As it was written to be handled by a
-// drag response, performance is hardly critical.
-// It's also kind of dumb to return the name which SetCombo then looks up,
-// but there's not a 1:1 correlation between offsets in the combo box and
-// in the list of formats.
-QString MainWindow::getFormatNameForExtension(QString ext)
-{
- for (int i = 0; i < formatList.size(); i++) {
- QStringList extensions = formatList[i].getExtensions();
- for (int j = 0; j < extensions.size(); ++j) {
- if (extensions[j] == ext) {
- return formatList[i].getName();;
- }
- }
- }
- return 0;
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: map.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include <QNetworkRequest>
+#include <QMessageBox>
+#include <QNetworkAccessManager>
+#include <QWebFrame>
+#include <QWebPage>
+#include <QApplication>
+#include <QCursor>
+#include <QFile>
+
+#include <math.h>
+#include "map.h"
+#include "appname.h"
+#include "dpencode.h"
+
+//------------------------------------------------------------------------
+static QString stripDoubleQuotes(const QString s) {
+ QString out;
+ foreach (QChar c, s) {
+ if (c != QChar('"'))
+ out += c;
+ }
+ return out;
+}
+
+//------------------------------------------------------------------------
+Map::Map(QWidget *parent,
+ const Gpx &gpx, QPlainTextEdit *te):
+ QWebView(parent),
+ gpx(gpx),
+ mapPresent(false),
+ busyCursor(false),
+ te(te)
+{
+ busyCursor = true;
+ stopWatch.start();
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ manager = new QNetworkAccessManager(this);
+ connect(this,SIGNAL(loadFinished(bool)),
+ this,SLOT(loadFinishedX(bool)));
+ this->logTimeX("Start map constuctor");
+ QString baseFile = QApplication::applicationDirPath() + "/gmapbase.html";
+ if (!QFile(baseFile).exists()) {
+ QMessageBox::critical(0, appName,
+ tr("Missing \"gmapbase.html\" file. Check installation"));
+ }
+ else {
+ QString urlStr = "file:///" + baseFile;
+ load(QUrl(urlStr));
+ }
+}
+
+//------------------------------------------------------------------------
+Map::~Map()
+{
+ if (busyCursor)
+ QApplication::restoreOverrideCursor();
+}
+//------------------------------------------------------------------------
+void Map::loadFinishedX(bool f)
+{
+ this->logTimeX("Done initial page load");
+ if (!f)
+ QMessageBox::critical(0, appName,
+ tr("Failed to load Google maps base page"));
+ else {
+ QApplication::processEvents();
+ showGpxData();
+ }
+ QApplication::restoreOverrideCursor();
+ busyCursor = false;
+}
+
+//------------------------------------------------------------------------
+
+static QStringList makeLiteralVar(const QString &name, const string &s)
+{
+ QStringList out;
+ out << QString("var %1 = ").arg(name);
+
+ QString ws = "\"";
+ for (unsigned int i=0; i<s.length(); i++) {
+ if (s[i] =='\\') {
+ ws += s[i];
+ }
+ ws += s[i];
+ if (ws.length() > 5120) {
+ ws += "\" + ";
+ out << ws;
+ ws = "\"";
+ }
+ }
+ ws += "\";";
+ out << ws;
+ return out;
+}
+
+//------------------------------------------------------------------------
+static QString fmtLatLng(const LatLng &l) {
+ return QString("%1, %3").arg(l.lat(), 0, 'f', 5) .arg(l.lng(), 0, 'f', 5);
+}
+
+//------------------------------------------------------------------------
+void Map::showGpxData()
+{
+ MarkerClicker *mclicker = new MarkerClicker(this);
+ this->page()->mainFrame()->addToJavaScriptWindowObject("mclicker", mclicker);
+ connect(mclicker, SIGNAL(markerClicked(int, int )), this, SLOT(markerClicked(int, int)));
+ connect(mclicker, SIGNAL(logTime(const QString &)), this, SLOT(logTimeX(const QString &)));
+
+ // It is appreciably faster to do the encoding on the C++ side.
+ int numLevels = 18;
+ double zoomFactor = 2;
+ PolylineEncoder encoder(numLevels, zoomFactor, 0.00001);
+
+
+ this->logTimeX("Start defining JS string");
+ QStringList scriptStr;
+ scriptStr
+ << "mclicker.logTime(\"Start JS execution\");"
+ << "var map = new GMap2(document.getElementById(\"map\"));"
+ << "var bounds = new GLatLngBounds;"
+ << "var waypts = [];"
+ << "var rtes = [];"
+ << "var trks = [];"
+ << "map.enableScrollWheelZoom();"
+ << "map.enableContinuousZoom();"
+ << "map.addControl(new GLargeMapControl());"
+ << "map.addControl(new GScaleControl());"
+ << "map.addControl(new GMapTypeControl());"
+ << "var pn = map.getPane(G_MAP_MARKER_PANE);"
+ << "pn.style.KhtmlUserSelect='none';"
+ << "pn.style.KhtmlUserDrag='none';"
+ << "mclicker.logTime(\"Done prelim JS definition\");"
+ << QString("var zoomFactor = %1;").arg(zoomFactor)
+ << QString("var numLevels = %1;").arg(numLevels)
+ ;
+
+ mapPresent = true;
+
+ // Waypoints.
+ int num=0;
+ foreach (const GpxWaypoint &pt, gpx.getWaypoints() ) {
+ scriptStr
+ << QString("waypts[%1] = new GMarker(new GLatLng(%2), "
+ "{title:\"%3\",icon:blueIcon});")
+ .arg(num)
+ .arg(fmtLatLng(pt.getLocation()))
+ .arg(stripDoubleQuotes(pt.getName()));
+ num++;
+ }
+
+ scriptStr
+ << "for( var i=0; i<waypts.length; ++i ) {"
+ << " bounds.extend(waypts[i].getPoint());"
+ << " var ftemp = new MarkerHandler(0, i);"
+ << " GEvent.bind(waypts[i], \"click\", ftemp, ftemp.clicked);"
+ << " map.addOverlay(waypts[i]);"
+ << "}"
+ << "mclicker.logTime(\"Done waypoints definition\");"
+ ;
+
+ // Tracks
+ num = 0;
+ foreach (const GpxTrack &trk, gpx.getTracks()) {
+ vector <LatLng> epts;
+ foreach (const GpxTrackSegment seg, trk.getTrackSegments()) {
+ foreach (const GpxTrackPoint pt, seg.getTrackPoints()) {
+ epts.push_back(pt.getLocation());
+ }
+ }
+ string encPts, encLevels;
+ encoder.dpEncode(encPts, encLevels, epts);
+
+ scriptStr
+ << QString("var startPt = new GLatLng(%1);").arg(fmtLatLng(epts[0]))
+ << QString("var endPt = new GLatLng(%1);").arg(fmtLatLng(epts[epts.size()-1]))
+ << QString("var idx = %1;").arg(num)
+ << QString("var nm = \"%1\";").arg(stripDoubleQuotes(trk.getName()))
+ << makeLiteralVar("encpts", encPts)
+ << makeLiteralVar("enclvs", encLevels)
+
+ << "var trk = GPolyline.fromEncoded({color:\"#0000E0\", weight:2, opacity:0.6,"
+ << "points:encpts, zoomFactor:zoomFactor, levels:enclvs, numLevels:numLevels});"
+ << "trks[idx] = new RTPolyline(trk, startPt, endPt, new MarkerHandler(1, idx));"
+ ;
+ num++;
+ }
+
+ scriptStr
+ << "for( var i=0; i<trks.length; ++i ) {"
+ << " var trkbound = trks[i].getBounds();"
+ << " bounds.extend(trkbound.getSouthWest());"
+ << " bounds.extend(trkbound.getNorthEast());"
+ << "}"
+ << "mclicker.logTime(\"Done track definition\");"
+ ;
+
+ // Routes
+ num = 0;
+ foreach (const GpxRoute &rte, gpx.getRoutes()) {
+ vector <LatLng> epts;
+ foreach (const GpxRoutePoint &pt, rte.getRoutePoints()) {
+ epts.push_back(pt.getLocation());
+ }
+ string encPts, encLevels;
+ encoder.dpEncode(encPts, encLevels, epts);
+ scriptStr
+ << QString("var startPt = new GLatLng(%1);").arg(fmtLatLng(epts[0]))
+ << QString("var endPt = new GLatLng(%1);").arg(fmtLatLng(epts[epts.size()-1]))
+ << QString("var idx = %1;").arg(num)
+ << QString("var nm = \"%1\";").arg(stripDoubleQuotes(rte.getName()))
+ << makeLiteralVar("encpts", encPts)
+ << makeLiteralVar("enclvs", encLevels)
+ << "var rte = GPolyline.fromEncoded({color:\"#8000B0\", weight:2, opacity:0.6,"
+ << " points:encpts, zoomFactor:zoomFactor, levels:enclvs, numLevels:numLevels});"
+ << "rtes[idx] = new RTPolyline(rte, startPt, endPt, new MarkerHandler(2, idx));"
+ ;
+ num++;
+ }
+
+ scriptStr
+ << "for( var i=0; i<rtes.length; ++i ) {"
+ << " var rtebound = rtes[i].getBounds();"
+ << " bounds.extend(rtebound.getSouthWest());"
+ << " bounds.extend(rtebound.getNorthEast());"
+ << "}"
+ << "mclicker.logTime(\"Done route definition\");"
+ ;
+
+ scriptStr
+ << "map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));"
+ << "mclicker.logTime(\"done setCenter\");"
+ ;
+
+ this->logTimeX("Done defining JS string");
+ evaluateJS(scriptStr);
+ this->logTimeX("Done JS evaluation");
+}
+
+//------------------------------------------------------------------------
+void Map::markerClicked(int t, int i){
+ if (t == 0)
+ emit waypointClicked(i);
+ else if (t == 1)
+ emit trackClicked(i);
+ else if (t == 2)
+ emit routeClicked(i);
+
+}
+
+//------------------------------------------------------------------------
+void Map::logTimeX(const QString &s)
+{
+ // fprintf(stderr, "Log: %s: %d ms\n", s.toStdString().c_str(), stopWatch.elapsed());
+ if (te) {
+ te->appendPlainText(QString("%1: %2 ms").arg(s).arg(stopWatch.elapsed()));
+ }
+ stopWatch.start();
+}
+//------------------------------------------------------------------------
+void Map::showTracks(const QList<GpxTrack> &tracks)
+{
+ QStringList scriptStr;
+ int i=0;
+ foreach(const GpxTrack &trk, tracks) {
+ scriptStr << QString("trks[%1].%2();").arg(i).arg(trk.getVisible()?"show":"hide");
+ i++;
+ }
+ evaluateJS(scriptStr);
+}
+
+//------------------------------------------------------------------------
+void Map::hideAllTracks()
+{
+ QStringList scriptStr;
+ scriptStr
+ << "for( var i=0; i<trks.length; ++i ) {"
+ << " trks[i].hide();"
+ << "}"
+ ;
+ evaluateJS(scriptStr);
+}
+
+//------------------------------------------------------------------------
+void Map::showWaypoints(const QList<GpxWaypoint> &waypoints)
+{
+ QStringList scriptStr;
+ int i=0;
+ foreach(const GpxWaypoint &pt, waypoints) {
+ scriptStr << QString("waypts[%1].%2();").arg(i++).arg(pt.getVisible()?"show":"hide");
+ }
+ evaluateJS(scriptStr);
+}
+//------------------------------------------------------------------------
+void Map::hideAllWaypoints()
+{
+ QStringList scriptStr;
+ scriptStr
+ << "for( var i=0; i<waypts.length; ++i ) {"
+ << " waypts[i].hide();"
+ << "}"
+ ;
+ evaluateJS(scriptStr);
+}
+
+//------------------------------------------------------------------------
+void Map::showRoutes(const QList<GpxRoute> &routes)
+{
+ QStringList scriptStr;
+ int i=0;
+ foreach(const GpxRoute &rt, routes) {
+ scriptStr << QString("rtes[%1].%2();").arg(i).arg(rt.getVisible()?"show":"hide");
+ i++;
+ }
+ evaluateJS(scriptStr);
+}
+//------------------------------------------------------------------------
+void Map::hideAllRoutes()
+{
+ QStringList scriptStr;
+ scriptStr
+ << "for( var i=0; i<rtes.length; ++i ) {"
+ << " rtes[i].hide();"
+ << "}"
+ ;
+ evaluateJS(scriptStr);
+}
+//------------------------------------------------------------------------
+void Map::setWaypointVisibility(int i, bool show)
+{
+ evaluateJS(QString("waypts[%1].%2();\n")
+ .arg(i).arg(show?"show": "hide"));
+}
+
+//------------------------------------------------------------------------
+void Map::setTrackVisibility(int i, bool show)
+{
+ QString x = show?"show": "hide";
+ QStringList scriptStr;
+ scriptStr
+ << QString("trks[%1].%2();").arg(i).arg(x)
+ ;
+ evaluateJS(scriptStr);
+}
+
+//------------------------------------------------------------------------
+void Map::setRouteVisibility(int i, bool show)
+{
+ QString x = show?"show": "hide";
+ QStringList scriptStr;
+ scriptStr
+ << QString("rtes[%1].%2();").arg(i).arg(x)
+ ;
+ evaluateJS(scriptStr);
+}
+
+//------------------------------------------------------------------------
+void Map::panTo(const LatLng &loc)
+{
+ evaluateJS(QString("map.panTo(new GLatLng(%1));").arg(fmtLatLng(loc)));
+}
+
+//------------------------------------------------------------------------
+void Map::resizeEvent ( QResizeEvent * ev)
+{
+ QWebView::resizeEvent(ev);
+ if (mapPresent)
+ evaluateJS(QString("map.checkResize();"));
+}
+
+//------------------------------------------------------------------------
+void Map::setWaypointColorRed(int i)
+{
+ evaluateJS(QString("waypts[%1].setImage(redIcon.image)").arg(i));
+}
+
+//------------------------------------------------------------------------
+void Map::setWaypointColorBlue(int i)
+{
+ evaluateJS(QString("waypts[%1].setImage(blueIcon.image)").arg(i));
+}
+
+//------------------------------------------------------------------------
+void Map::frameTrack(int i)
+{
+ QStringList scriptStr;
+ scriptStr
+ << QString("var trkbound = trks[%1].getBounds();").arg(i)
+ << "map.setCenter(trkbound.getCenter(), map.getBoundsZoomLevel(trkbound));"
+ ;
+ evaluateJS(scriptStr);
+}
+
+
+//------------------------------------------------------------------------
+void Map::frameRoute(int i)
+{
+ QStringList scriptStr;
+ scriptStr
+ << QString("var rtebound = rtes[%1].getBounds();").arg(i)
+ << "map.setCenter(rtebound.getCenter(), map.getBoundsZoomLevel(rtebound));"
+ ;
+ evaluateJS(scriptStr);
+}
+
+
+//------------------------------------------------------------------------
+void Map::evaluateJS(const QString &s, bool upd)
+{
+ this->page()->mainFrame()->evaluateJavaScript(s);
+ if (upd) {
+ this->update();
+ }
+}
+
+//------------------------------------------------------------------------
+void Map::evaluateJS(const QStringList &s, bool upd)
+{
+ evaluateJS(s.join("\n"), upd);
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: map.cpp,v 1.2 2009-08-28 17:08:55 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include <QNetworkRequest>
-#include <QMessageBox>
-#include <QNetworkAccessManager>
-#include <QWebFrame>
-#include <QWebPage>
-#include <QApplication>
-#include <QCursor>
-#include <QFile>
-
-#include <math.h>
-#include "map.h"
-#include "appname.h"
-#include "dpencode.h"
-
-//------------------------------------------------------------------------
-static QString stripDoubleQuotes(const QString s) {
- QString out;
- foreach (QChar c, s) {
- if (c != QChar('"'))
- out += c;
- }
- return out;
-}
-
-//------------------------------------------------------------------------
-Map::Map(QWidget *parent,
- const Gpx &gpx, QPlainTextEdit *te):
- QWebView(parent),
- gpx(gpx),
- mapPresent(false),
- busyCursor(false),
- te(te)
-{
- busyCursor = true;
- stopWatch.start();
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
- manager = new QNetworkAccessManager(this);
- connect(this,SIGNAL(loadFinished(bool)),
- this,SLOT(loadFinishedX(bool)));
- this->logTimeX("Start map constuctor");
- QString baseFile = QApplication::applicationDirPath() + "/gmapbase.html";
- if (!QFile(baseFile).exists()) {
- QMessageBox::critical(0, appName,
- tr("Missing \"gmapbase.html\" file. Check installation"));
- }
- else {
- QString urlStr = "file:///" + baseFile;
- load(QUrl(urlStr));
- }
-}
-
-//------------------------------------------------------------------------
-Map::~Map()
-{
- if (busyCursor)
- QApplication::restoreOverrideCursor();
-}
-//------------------------------------------------------------------------
-void Map::loadFinishedX(bool f)
-{
- this->logTimeX("Done initial page load");
- if (!f)
- QMessageBox::critical(0, appName,
- tr("Failed to load Google maps base page"));
- else {
- QApplication::processEvents();
- showGpxData();
- }
- QApplication::restoreOverrideCursor();
- busyCursor = false;
-}
-
-//------------------------------------------------------------------------
-
-static QStringList makeLiteralVar(const QString &name, const string &s)
-{
- QStringList out;
- out << QString("var %1 = ").arg(name);
-
- QString ws = "\"";
- for (unsigned int i=0; i<s.length(); i++) {
- if (s[i] =='\\') {
- ws += s[i];
- }
- ws += s[i];
- if (ws.length() > 5120) {
- ws += "\" + ";
- out << ws;
- ws = "\"";
- }
- }
- ws += "\";";
- out << ws;
- return out;
-}
-
-//------------------------------------------------------------------------
-static QString fmtLatLng(const LatLng &l) {
- return QString("%1, %3").arg(l.lat(), 0, 'f', 5) .arg(l.lng(), 0, 'f', 5);
-}
-
-//------------------------------------------------------------------------
-void Map::showGpxData()
-{
- MarkerClicker *mclicker = new MarkerClicker(this);
- this->page()->mainFrame()->addToJavaScriptWindowObject("mclicker", mclicker);
- connect(mclicker, SIGNAL(markerClicked(int, int )), this, SLOT(markerClicked(int, int)));
- connect(mclicker, SIGNAL(logTime(const QString &)), this, SLOT(logTimeX(const QString &)));
-
- // It is appreciably faster to do the encoding on the C++ side.
- int numLevels = 18;
- double zoomFactor = 2;
- PolylineEncoder encoder(numLevels, zoomFactor, 0.00001);
-
-
- this->logTimeX("Start defining JS string");
- QStringList scriptStr;
- scriptStr
- << "mclicker.logTime(\"Start JS execution\");"
- << "var map = new GMap2(document.getElementById(\"map\"));"
- << "var bounds = new GLatLngBounds;"
- << "var waypts = [];"
- << "var rtes = [];"
- << "var trks = [];"
- << "map.enableScrollWheelZoom();"
- << "map.enableContinuousZoom();"
- << "map.addControl(new GLargeMapControl());"
- << "map.addControl(new GScaleControl());"
- << "map.addControl(new GMapTypeControl());"
- << "var pn = map.getPane(G_MAP_MARKER_PANE);"
- << "pn.style.KhtmlUserSelect='none';"
- << "pn.style.KhtmlUserDrag='none';"
- << "mclicker.logTime(\"Done prelim JS definition\");"
- << QString("var zoomFactor = %1;").arg(zoomFactor)
- << QString("var numLevels = %1;").arg(numLevels)
- ;
-
- mapPresent = true;
-
- // Waypoints.
- int num=0;
- foreach (const GpxWaypoint &pt, gpx.getWaypoints() ) {
- scriptStr
- << QString("waypts[%1] = new GMarker(new GLatLng(%2), "
- "{title:\"%3\",icon:blueIcon});")
- .arg(num)
- .arg(fmtLatLng(pt.getLocation()))
- .arg(stripDoubleQuotes(pt.getName()));
- num++;
- }
-
- scriptStr
- << "for( var i=0; i<waypts.length; ++i ) {"
- << " bounds.extend(waypts[i].getPoint());"
- << " var ftemp = new MarkerHandler(0, i);"
- << " GEvent.bind(waypts[i], \"click\", ftemp, ftemp.clicked);"
- << " map.addOverlay(waypts[i]);"
- << "}"
- << "mclicker.logTime(\"Done waypoints definition\");"
- ;
-
- // Tracks
- num = 0;
- foreach (const GpxTrack &trk, gpx.getTracks()) {
- vector <LatLng> epts;
- foreach (const GpxTrackSegment seg, trk.getTrackSegments()) {
- foreach (const GpxTrackPoint pt, seg.getTrackPoints()) {
- epts.push_back(pt.getLocation());
- }
- }
- string encPts, encLevels;
- encoder.dpEncode(encPts, encLevels, epts);
-
- scriptStr
- << QString("var startPt = new GLatLng(%1);").arg(fmtLatLng(epts[0]))
- << QString("var endPt = new GLatLng(%1);").arg(fmtLatLng(epts[epts.size()-1]))
- << QString("var idx = %1;").arg(num)
- << QString("var nm = \"%1\";").arg(stripDoubleQuotes(trk.getName()))
- << makeLiteralVar("encpts", encPts)
- << makeLiteralVar("enclvs", encLevels)
-
- << "var trk = GPolyline.fromEncoded({color:\"#0000E0\", weight:2, opacity:0.6,"
- << "points:encpts, zoomFactor:zoomFactor, levels:enclvs, numLevels:numLevels});"
- << "trks[idx] = new RTPolyline(trk, startPt, endPt, new MarkerHandler(1, idx));"
- ;
- num++;
- }
-
- scriptStr
- << "for( var i=0; i<trks.length; ++i ) {"
- << " var trkbound = trks[i].getBounds();"
- << " bounds.extend(trkbound.getSouthWest());"
- << " bounds.extend(trkbound.getNorthEast());"
- << "}"
- << "mclicker.logTime(\"Done track definition\");"
- ;
-
- // Routes
- num = 0;
- foreach (const GpxRoute &rte, gpx.getRoutes()) {
- vector <LatLng> epts;
- foreach (const GpxRoutePoint &pt, rte.getRoutePoints()) {
- epts.push_back(pt.getLocation());
- }
- string encPts, encLevels;
- encoder.dpEncode(encPts, encLevels, epts);
- scriptStr
- << QString("var startPt = new GLatLng(%1);").arg(fmtLatLng(epts[0]))
- << QString("var endPt = new GLatLng(%1);").arg(fmtLatLng(epts[epts.size()-1]))
- << QString("var idx = %1;").arg(num)
- << QString("var nm = \"%1\";").arg(stripDoubleQuotes(rte.getName()))
- << makeLiteralVar("encpts", encPts)
- << makeLiteralVar("enclvs", encLevels)
- << "var rte = GPolyline.fromEncoded({color:\"#8000B0\", weight:2, opacity:0.6,"
- << " points:encpts, zoomFactor:zoomFactor, levels:enclvs, numLevels:numLevels});"
- << "rtes[idx] = new RTPolyline(rte, startPt, endPt, new MarkerHandler(2, idx));"
- ;
- num++;
- }
-
- scriptStr
- << "for( var i=0; i<rtes.length; ++i ) {"
- << " var rtebound = rtes[i].getBounds();"
- << " bounds.extend(rtebound.getSouthWest());"
- << " bounds.extend(rtebound.getNorthEast());"
- << "}"
- << "mclicker.logTime(\"Done route definition\");"
- ;
-
- scriptStr
- << "map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));"
- << "mclicker.logTime(\"done setCenter\");"
- ;
-
- this->logTimeX("Done defining JS string");
- evaluateJS(scriptStr);
- this->logTimeX("Done JS evaluation");
-}
-
-//------------------------------------------------------------------------
-void Map::markerClicked(int t, int i){
- if (t == 0)
- emit waypointClicked(i);
- else if (t == 1)
- emit trackClicked(i);
- else if (t == 2)
- emit routeClicked(i);
-
-}
-
-//------------------------------------------------------------------------
-void Map::logTimeX(const QString &s)
-{
- // fprintf(stderr, "Log: %s: %d ms\n", s.toStdString().c_str(), stopWatch.elapsed());
- if (te) {
- te->appendPlainText(QString("%1: %2 ms").arg(s).arg(stopWatch.elapsed()));
- }
- stopWatch.start();
-}
-//------------------------------------------------------------------------
-void Map::showTracks(const QList<GpxTrack> &tracks)
-{
- QStringList scriptStr;
- int i=0;
- foreach(const GpxTrack &trk, tracks) {
- scriptStr << QString("trks[%1].%2();").arg(i).arg(trk.getVisible()?"show":"hide");
- i++;
- }
- evaluateJS(scriptStr);
-}
-
-//------------------------------------------------------------------------
-void Map::hideAllTracks()
-{
- QStringList scriptStr;
- scriptStr
- << "for( var i=0; i<trks.length; ++i ) {"
- << " trks[i].hide();"
- << "}"
- ;
- evaluateJS(scriptStr);
-}
-
-//------------------------------------------------------------------------
-void Map::showWaypoints(const QList<GpxWaypoint> &waypoints)
-{
- QStringList scriptStr;
- int i=0;
- foreach(const GpxWaypoint &pt, waypoints) {
- scriptStr << QString("waypts[%1].%2();").arg(i++).arg(pt.getVisible()?"show":"hide");
- }
- evaluateJS(scriptStr);
-}
-//------------------------------------------------------------------------
-void Map::hideAllWaypoints()
-{
- QStringList scriptStr;
- scriptStr
- << "for( var i=0; i<waypts.length; ++i ) {"
- << " waypts[i].hide();"
- << "}"
- ;
- evaluateJS(scriptStr);
-}
-
-//------------------------------------------------------------------------
-void Map::showRoutes(const QList<GpxRoute> &routes)
-{
- QStringList scriptStr;
- int i=0;
- foreach(const GpxRoute &rt, routes) {
- scriptStr << QString("rtes[%1].%2();").arg(i).arg(rt.getVisible()?"show":"hide");
- i++;
- }
- evaluateJS(scriptStr);
-}
-//------------------------------------------------------------------------
-void Map::hideAllRoutes()
-{
- QStringList scriptStr;
- scriptStr
- << "for( var i=0; i<rtes.length; ++i ) {"
- << " rtes[i].hide();"
- << "}"
- ;
- evaluateJS(scriptStr);
-}
-//------------------------------------------------------------------------
-void Map::setWaypointVisibility(int i, bool show)
-{
- evaluateJS(QString("waypts[%1].%2();\n")
- .arg(i).arg(show?"show": "hide"));
-}
-
-//------------------------------------------------------------------------
-void Map::setTrackVisibility(int i, bool show)
-{
- QString x = show?"show": "hide";
- QStringList scriptStr;
- scriptStr
- << QString("trks[%1].%2();").arg(i).arg(x)
- ;
- evaluateJS(scriptStr);
-}
-
-//------------------------------------------------------------------------
-void Map::setRouteVisibility(int i, bool show)
-{
- QString x = show?"show": "hide";
- QStringList scriptStr;
- scriptStr
- << QString("rtes[%1].%2();").arg(i).arg(x)
- ;
- evaluateJS(scriptStr);
-}
-
-//------------------------------------------------------------------------
-void Map::panTo(const LatLng &loc)
-{
- evaluateJS(QString("map.panTo(new GLatLng(%1));").arg(fmtLatLng(loc)));
-}
-
-//------------------------------------------------------------------------
-void Map::resizeEvent ( QResizeEvent * ev)
-{
- QWebView::resizeEvent(ev);
- if (mapPresent)
- evaluateJS(QString("map.checkResize();"));
-}
-
-//------------------------------------------------------------------------
-void Map::setWaypointColorRed(int i)
-{
- evaluateJS(QString("waypts[%1].setImage(redIcon.image)").arg(i));
-}
-
-//------------------------------------------------------------------------
-void Map::setWaypointColorBlue(int i)
-{
- evaluateJS(QString("waypts[%1].setImage(blueIcon.image)").arg(i));
-}
-
-//------------------------------------------------------------------------
-void Map::frameTrack(int i)
-{
- QStringList scriptStr;
- scriptStr
- << QString("var trkbound = trks[%1].getBounds();").arg(i)
- << "map.setCenter(trkbound.getCenter(), map.getBoundsZoomLevel(trkbound));"
- ;
- evaluateJS(scriptStr);
-}
-
-
-//------------------------------------------------------------------------
-void Map::frameRoute(int i)
-{
- QStringList scriptStr;
- scriptStr
- << QString("var rtebound = rtes[%1].getBounds();").arg(i)
- << "map.setCenter(rtebound.getCenter(), map.getBoundsZoomLevel(rtebound));"
- ;
- evaluateJS(scriptStr);
-}
-
-
-//------------------------------------------------------------------------
-void Map::evaluateJS(const QString &s, bool upd)
-{
- this->page()->mainFrame()->evaluateJavaScript(s);
- if (upd) {
- this->update();
- }
-}
-
-//------------------------------------------------------------------------
-void Map::evaluateJS(const QStringList &s, bool upd)
-{
- evaluateJS(s.join("\n"), upd);
-}
--- /dev/null
+// -*- C++ -*-
+// $Id: optionsdlg.cpp,v 1.5 2010-03-01 04:22:28 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+
+#include <QVBoxLayout>
+#include <QDoubleValidator>
+#include <QIntValidator>
+#include <QPushButton>
+#include <QFileDialog>
+#include <QIcon>
+#include <QSpinBox>
+#include "optionsdlg.h"
+#include "help.h"
+
+//------------------------------------------------------------------------
+static void SetSizeStuff(QWidget *w)
+{
+ QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+ sizePolicy.setHorizontalStretch(0);
+ sizePolicy.setVerticalStretch(0);
+ sizePolicy.setHeightForWidth(w->sizePolicy().hasHeightForWidth());
+ w->setSizePolicy(sizePolicy);
+}
+
+//------------------------------------------------------------------------
+FileDlgManager::FileDlgManager(QObject*parent,
+ QLineEdit *le,
+ QToolButton *tb, bool isInFile):
+ QObject(parent), le(le), tb(tb), isInFile(isInFile)
+{
+ connect(tb, SIGNAL(clicked()), this, SLOT(buttonClicked()));
+}
+
+//------------------------------------------------------------------------
+QVariant getOptionValue(QList<FormatOption> opts, int k) {
+ if (opts[k].getValue().toString() != "")
+ return opts[k].getValue();
+ else
+ return opts[k].getDefaultValue();
+}
+
+//------------------------------------------------------------------------
+FileDlgManager::~FileDlgManager()
+{
+}
+//------------------------------------------------------------------------
+void FileDlgManager::buttonClicked()
+{
+ QString str;
+ if (isInFile) {
+ str = QFileDialog::getOpenFileName(0, tr("Select input file"),
+ le->text(),
+ "All Files (*.*)");
+ }
+ else {
+ str = QFileDialog::getSaveFileName(0, tr("Select output file"),
+ le->text(),
+ "All Files (*.*)");
+ }
+ if (str != "")
+ le->setText(str);
+}
+
+//------------------------------------------------------------------------
+OptionsDlg::OptionsDlg(QWidget*parent, const QString &fmtName, QList<FormatOption> *opts,
+ const QString &html):
+ QDialog(parent),
+ fmtName(fmtName),
+ options(*opts),
+ html(html)
+{
+
+ QVBoxLayout *verticalLayout = new QVBoxLayout(this);
+ for (int k=0; k<options.size(); k++) {
+ QHBoxLayout *horizontalLayout = new QHBoxLayout();
+
+ QCheckBox *checkBox = new QCheckBox(this);
+ checkBox->setText(tr(options[k].getDescription().toAscii().data()));
+ horizontalLayout->addWidget(checkBox);
+ checkBox->setChecked(options[k].getSelected());
+ //checkBox->setWhatsThis(options[k].getHtml());
+
+ QSpacerItem *horizontalSpacer = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+ horizontalLayout->addItem(horizontalSpacer);
+
+ QWidget *w = 0;
+ switch (options[k].getType())
+ {
+ case FormatOption::OPTstring:
+ {
+ QLineEdit *lineEdit = new QLineEdit(this);
+ SetSizeStuff(lineEdit);
+ lineEdit->setText(getOptionValue(options, k).toString());
+ w = lineEdit;
+ horizontalLayout->addWidget(lineEdit);
+ }
+ break;
+
+ case FormatOption::OPTinFile:
+ case FormatOption::OPToutFile:
+ {
+ bool inFile = options[k].getType() == FormatOption::OPTinFile;
+ QLineEdit *lineEdit = new QLineEdit(this);
+ QToolButton *button = new QToolButton(this);
+ lineEdit->setText(getOptionValue(options, k).toString());
+ button->setIcon(QIcon(inFile ? ":images/file.png" : ":images/save.png" ));
+ w = lineEdit;
+ horizontalSpacer->changeSize(5, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
+ horizontalLayout->addWidget(lineEdit);
+ horizontalLayout->addWidget(button);
+ (void) new FileDlgManager(this, lineEdit, button, inFile);
+ }
+ break;
+
+ case FormatOption::OPTbool:
+ // This is quirky. It means that GPSBabel's bool options that default
+ // to true get turned on here, even if user turned them off on last
+ // exit.
+ checkBox->setChecked(getOptionValue(options,k).toBool());
+ w = 0;
+ break;
+
+ case FormatOption::OPTfloat:
+ {
+ QLineEdit *lineEdit = new QLineEdit(this);
+ SetSizeStuff(lineEdit);
+ lineEdit->setText(getOptionValue(options, k).toString());
+ w = lineEdit;
+ QDoubleValidator *v = new QDoubleValidator(this);
+ v->setRange(options[k].getMinValue().toDouble(),
+ options[k].getMaxValue().toDouble());
+ lineEdit->setValidator(v);
+ horizontalLayout->addWidget(lineEdit);
+ }
+ break;
+
+ case FormatOption::OPTint:
+ {
+ QLineEdit *lineEdit = new QLineEdit(this);
+ SetSizeStuff(lineEdit);
+ w = lineEdit;
+ QIntValidator *iv = new QIntValidator(this);
+ iv->setRange(options[k].getMinValue().toInt(),
+ options[k].getMaxValue().toInt());
+ lineEdit->setValidator(iv);
+ lineEdit->setText(getOptionValue(options, k).toString());
+ horizontalLayout->addWidget(lineEdit);
+ }
+ break;
+
+ case FormatOption::OPTboundedInt:
+ {
+ QSpinBox *spinBox = new QSpinBox(this);
+ spinBox->setRange(options[k].getMinValue().toInt(),
+ options[k].getMaxValue().toInt());
+ spinBox->setValue(getOptionValue(options, k).toInt());
+ SetSizeStuff(spinBox);
+ w = spinBox;
+ horizontalLayout->addWidget(spinBox);
+ }
+ break;
+ }
+ checkBoxes.push_back(checkBox);
+ fields.push_back(w);
+
+ verticalLayout->addLayout(horizontalLayout);
+ }
+ QPushButton *helpButton = new QPushButton(this);
+ helpButton->setIcon(QIcon(":/images/help.png"));
+ helpButton->setText(tr("Help"));
+
+ QHBoxLayout *lay = new QHBoxLayout();
+ lay->addWidget(helpButton);
+
+ buttonBox = new QDialogButtonBox(this);
+ buttonBox->setOrientation(Qt::Horizontal);
+ buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+ lay->addWidget(buttonBox);
+ verticalLayout->addLayout(lay);
+ buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
+ buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
+
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
+ connect(helpButton, SIGNAL(clicked()), this, SLOT(helpClicked()));
+}
+
+//------------------------------------------------------------------------
+void OptionsDlg::acceptClicked()
+{
+ for (int k=0; k<options.size(); k++) {
+ options[k].setSelected(checkBoxes[k]->isChecked());
+ if (fields[k]) {
+ if (options[k].getType() == FormatOption::OPTboundedInt) {
+ int value = static_cast<QSpinBox*>(fields[k])->value();
+ value = qMax(qMin(value, options[k].getMaxValue().toInt()),options[k].getMinValue().toInt());
+ options[k].setValue(QVariant(value));
+ }
+ else if (options[k].getType() == FormatOption::OPTint) {
+ int value = static_cast<QLineEdit*>(fields[k])->text().toInt();
+ value = qMax(qMin(value, options[k].getMaxValue().toInt()),options[k].getMinValue().toInt());
+ options[k].setValue(QVariant(value));
+ }
+ else if (options[k].getType() == FormatOption::OPTfloat) {
+ double value = static_cast<QLineEdit*>(fields[k])->text().toDouble();
+ value = qMax(qMin(value, options[k].getMaxValue().toDouble()),options[k].getMinValue().toDouble());
+ options[k].setValue(QVariant(value));
+ }
+ else
+ options[k].setValue(static_cast<QLineEdit*>(fields[k])->text());
+ }
+ }
+ accept();
+}
+
+//------------------------------------------------------------------------
+void OptionsDlg::rejectClicked()
+{
+ reject();
+}
+
+//------------------------------------------------------------------------
+void OptionsDlg::helpClicked()
+{
+ ShowHelp(html);
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: optionsdlg.cpp,v 1.5 2010-03-01 04:22:28 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-
-#include <QVBoxLayout>
-#include <QDoubleValidator>
-#include <QIntValidator>
-#include <QPushButton>
-#include <QFileDialog>
-#include <QIcon>
-#include <QSpinBox>
-#include "optionsdlg.h"
-#include "help.h"
-
-//------------------------------------------------------------------------
-static void SetSizeStuff(QWidget *w)
-{
- QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(w->sizePolicy().hasHeightForWidth());
- w->setSizePolicy(sizePolicy);
-}
-
-//------------------------------------------------------------------------
-FileDlgManager::FileDlgManager(QObject*parent,
- QLineEdit *le,
- QToolButton *tb, bool isInFile):
- QObject(parent), le(le), tb(tb), isInFile(isInFile)
-{
- connect(tb, SIGNAL(clicked()), this, SLOT(buttonClicked()));
-}
-
-//------------------------------------------------------------------------
-QVariant getOptionValue(QList<FormatOption> opts, int k) {
- if (opts[k].getValue().toString() != "")
- return opts[k].getValue();
- else
- return opts[k].getDefaultValue();
-}
-
-//------------------------------------------------------------------------
-FileDlgManager::~FileDlgManager()
-{
-}
-//------------------------------------------------------------------------
-void FileDlgManager::buttonClicked()
-{
- QString str;
- if (isInFile) {
- str = QFileDialog::getOpenFileName(0, tr("Select input file"),
- le->text(),
- "All Files (*.*)");
- }
- else {
- str = QFileDialog::getSaveFileName(0, tr("Select output file"),
- le->text(),
- "All Files (*.*)");
- }
- if (str != "")
- le->setText(str);
-}
-
-//------------------------------------------------------------------------
-OptionsDlg::OptionsDlg(QWidget*parent, const QString &fmtName, QList<FormatOption> *opts,
- const QString &html):
- QDialog(parent),
- fmtName(fmtName),
- options(*opts),
- html(html)
-{
-
- QVBoxLayout *verticalLayout = new QVBoxLayout(this);
- for (int k=0; k<options.size(); k++) {
- QHBoxLayout *horizontalLayout = new QHBoxLayout();
-
- QCheckBox *checkBox = new QCheckBox(this);
- checkBox->setText(tr(options[k].getDescription().toAscii().data()));
- horizontalLayout->addWidget(checkBox);
- checkBox->setChecked(options[k].getSelected());
- //checkBox->setWhatsThis(options[k].getHtml());
-
- QSpacerItem *horizontalSpacer = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
- horizontalLayout->addItem(horizontalSpacer);
-
- QWidget *w = 0;
- switch (options[k].getType())
- {
- case FormatOption::OPTstring:
- {
- QLineEdit *lineEdit = new QLineEdit(this);
- SetSizeStuff(lineEdit);
- lineEdit->setText(getOptionValue(options, k).toString());
- w = lineEdit;
- horizontalLayout->addWidget(lineEdit);
- }
- break;
-
- case FormatOption::OPTinFile:
- case FormatOption::OPToutFile:
- {
- bool inFile = options[k].getType() == FormatOption::OPTinFile;
- QLineEdit *lineEdit = new QLineEdit(this);
- QToolButton *button = new QToolButton(this);
- lineEdit->setText(getOptionValue(options, k).toString());
- button->setIcon(QIcon(inFile ? ":images/file.png" : ":images/save.png" ));
- w = lineEdit;
- horizontalSpacer->changeSize(5, 20, QSizePolicy::Fixed, QSizePolicy::Minimum);
- horizontalLayout->addWidget(lineEdit);
- horizontalLayout->addWidget(button);
- (void) new FileDlgManager(this, lineEdit, button, inFile);
- }
- break;
-
- case FormatOption::OPTbool:
- // This is quirky. It means that GPSBabel's bool options that default
- // to true get turned on here, even if user turned them off on last
- // exit.
- checkBox->setChecked(getOptionValue(options,k).toBool());
- w = 0;
- break;
-
- case FormatOption::OPTfloat:
- {
- QLineEdit *lineEdit = new QLineEdit(this);
- SetSizeStuff(lineEdit);
- lineEdit->setText(getOptionValue(options, k).toString());
- w = lineEdit;
- QDoubleValidator *v = new QDoubleValidator(this);
- v->setRange(options[k].getMinValue().toDouble(),
- options[k].getMaxValue().toDouble());
- lineEdit->setValidator(v);
- horizontalLayout->addWidget(lineEdit);
- }
- break;
-
- case FormatOption::OPTint:
- {
- QLineEdit *lineEdit = new QLineEdit(this);
- SetSizeStuff(lineEdit);
- w = lineEdit;
- QIntValidator *iv = new QIntValidator(this);
- iv->setRange(options[k].getMinValue().toInt(),
- options[k].getMaxValue().toInt());
- lineEdit->setValidator(iv);
- lineEdit->setText(getOptionValue(options, k).toString());
- horizontalLayout->addWidget(lineEdit);
- }
- break;
-
- case FormatOption::OPTboundedInt:
- {
- QSpinBox *spinBox = new QSpinBox(this);
- spinBox->setRange(options[k].getMinValue().toInt(),
- options[k].getMaxValue().toInt());
- spinBox->setValue(getOptionValue(options, k).toInt());
- SetSizeStuff(spinBox);
- w = spinBox;
- horizontalLayout->addWidget(spinBox);
- }
- break;
- }
- checkBoxes.push_back(checkBox);
- fields.push_back(w);
-
- verticalLayout->addLayout(horizontalLayout);
- }
- QPushButton *helpButton = new QPushButton(this);
- helpButton->setIcon(QIcon(":/images/help.png"));
- helpButton->setText(tr("Help"));
-
- QHBoxLayout *lay = new QHBoxLayout();
- lay->addWidget(helpButton);
-
- buttonBox = new QDialogButtonBox(this);
- buttonBox->setOrientation(Qt::Horizontal);
- buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
- lay->addWidget(buttonBox);
- verticalLayout->addLayout(lay);
- buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon(":images/ok"));
- buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon(":images/cancel"));
-
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
- connect(buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
- connect(helpButton, SIGNAL(clicked()), this, SLOT(helpClicked()));
-}
-
-//------------------------------------------------------------------------
-void OptionsDlg::acceptClicked()
-{
- for (int k=0; k<options.size(); k++) {
- options[k].setSelected(checkBoxes[k]->isChecked());
- if (fields[k]) {
- if (options[k].getType() == FormatOption::OPTboundedInt) {
- int value = static_cast<QSpinBox*>(fields[k])->value();
- value = qMax(qMin(value, options[k].getMaxValue().toInt()),options[k].getMinValue().toInt());
- options[k].setValue(QVariant(value));
- }
- else if (options[k].getType() == FormatOption::OPTint) {
- int value = static_cast<QLineEdit*>(fields[k])->text().toInt();
- value = qMax(qMin(value, options[k].getMaxValue().toInt()),options[k].getMinValue().toInt());
- options[k].setValue(QVariant(value));
- }
- else if (options[k].getType() == FormatOption::OPTfloat) {
- double value = static_cast<QLineEdit*>(fields[k])->text().toDouble();
- value = qMax(qMin(value, options[k].getMaxValue().toDouble()),options[k].getMinValue().toDouble());
- options[k].setValue(QVariant(value));
- }
- else
- options[k].setValue(static_cast<QLineEdit*>(fields[k])->text());
- }
- }
- accept();
-}
-
-//------------------------------------------------------------------------
-void OptionsDlg::rejectClicked()
-{
- reject();
-}
-
-//------------------------------------------------------------------------
-void OptionsDlg::helpClicked()
-{
- ShowHelp(html);
-}
--- /dev/null
+//
+// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+
+
+#include "preferences.h"
+#include "../gbversion.h"
+
+class FormatListEntry : public QListWidgetItem {
+ public:
+ FormatListEntry(Format& fmt) : fmt_(fmt) {
+ setText(fmt.getDescription());
+ bool enabled = !fmt.isHidden();
+ setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
+ }
+
+ private:
+ Format& fmt_;
+};
+
+Preferences::Preferences(QWidget* parent, QList<Format>& formatList,
+ BabelData& bd) : QDialog(parent),
+ formatList_(formatList),
+ bd_(bd)
+{
+ ui_.setupUi(this);
+
+ ui_.startupCheck->setChecked(bd_.startupVersionCheck);
+ ui_.reportStatisticsCheck->setChecked(bd_.reportStatistics);
+ ui_.ignoreVersionMismatchCheck->setChecked(bd_.ignoreVersionMismatch);
+ // Because of an unfortunate bug in 1.4.0, we turn this off in 1.4.1.
+ if (VERSION == QString("1.4.1"))
+ bd_.ignoreVersionMismatch = false;
+
+ connect (ui_.buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
+ connect (ui_.buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
+
+ connect (ui_.enableAllButton, SIGNAL(clicked()), this, SLOT(enableAllClicked()));
+ connect (ui_.disableAllButton, SIGNAL(clicked()), this, SLOT(disableAllClicked()));
+
+ for (int i = 0; i < formatList_.size(); i++) {
+ FormatListEntry *item = new FormatListEntry(formatList[i]);
+
+ ui_.enabledFormatsList->addItem(item);
+ }
+}
+
+void Preferences::enableAllClicked()
+{
+ for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
+ QListWidgetItem* item = ui_.enabledFormatsList->item(i);
+ item->setCheckState(Qt::Checked);
+ }
+}
+
+void Preferences::disableAllClicked()
+{
+ for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
+ QListWidgetItem* item = ui_.enabledFormatsList->item(i);
+ item->setCheckState(Qt::Unchecked);
+ }
+}
+
+void Preferences::acceptClicked()
+{
+ for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
+ QListWidgetItem* item = ui_.enabledFormatsList->item(i);
+ formatList_[i].setHidden(item->checkState() == Qt::Unchecked);
+ }
+
+ bd_.startupVersionCheck = ui_.startupCheck->isChecked();
+ bd_.reportStatistics = ui_.reportStatisticsCheck->isChecked();
+ bd_.ignoreVersionMismatch = ui_.ignoreVersionMismatchCheck->isChecked();
+ accept();
+}
+
+void Preferences::rejectClicked()
+{
+ reject();
+}
+++ /dev/null
-//
-// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-
-
-#include "preferences.h"
-#include "../gbversion.h"
-
-class FormatListEntry : public QListWidgetItem {
- public:
- FormatListEntry(Format& fmt) : fmt_(fmt) {
- setText(fmt.getDescription());
- bool enabled = !fmt.isHidden();
- setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
- }
-
- private:
- Format& fmt_;
-};
-
-Preferences::Preferences(QWidget* parent, QList<Format>& formatList,
- BabelData& bd) : QDialog(parent),
- formatList_(formatList),
- bd_(bd)
-{
- ui_.setupUi(this);
-
- ui_.startupCheck->setChecked(bd_.startupVersionCheck);
- ui_.reportStatisticsCheck->setChecked(bd_.reportStatistics);
- ui_.ignoreVersionMismatchCheck->setChecked(bd_.ignoreVersionMismatch);
- // Because of an unfortunate bug in 1.4.0, we turn this off in 1.4.1.
- if (VERSION == QString("1.4.1"))
- bd_.ignoreVersionMismatch = false;
-
- connect (ui_.buttonBox, SIGNAL(accepted()), this, SLOT(acceptClicked()));
- connect (ui_.buttonBox, SIGNAL(rejected()), this, SLOT(rejectClicked()));
-
- connect (ui_.enableAllButton, SIGNAL(clicked()), this, SLOT(enableAllClicked()));
- connect (ui_.disableAllButton, SIGNAL(clicked()), this, SLOT(disableAllClicked()));
-
- for (int i = 0; i < formatList_.size(); i++) {
- FormatListEntry *item = new FormatListEntry(formatList[i]);
-
- ui_.enabledFormatsList->addItem(item);
- }
-}
-
-void Preferences::enableAllClicked()
-{
- for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
- QListWidgetItem* item = ui_.enabledFormatsList->item(i);
- item->setCheckState(Qt::Checked);
- }
-}
-
-void Preferences::disableAllClicked()
-{
- for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
- QListWidgetItem* item = ui_.enabledFormatsList->item(i);
- item->setCheckState(Qt::Unchecked);
- }
-}
-
-void Preferences::acceptClicked()
-{
- for (int i = 0; i < ui_.enabledFormatsList->count(); i++) {
- QListWidgetItem* item = ui_.enabledFormatsList->item(i);
- formatList_[i].setHidden(item->checkState() == Qt::Unchecked);
- }
-
- bd_.startupVersionCheck = ui_.startupCheck->isChecked();
- bd_.reportStatistics = ui_.reportStatisticsCheck->isChecked();
- bd_.ignoreVersionMismatch = ui_.ignoreVersionMismatchCheck->isChecked();
- accept();
-}
-
-void Preferences::rejectClicked()
-{
- reject();
-}
--- /dev/null
+// -*- c++ -*-
+// $Id: processwait.cpp,v 1.3 2009-08-28 17:08:55 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+//------------------------------------------------------------------------
+#include <QProcess>
+#include <QStringList>
+#include <QPlainTextEdit>
+#include <QDialogButtonBox>
+#include <QVBoxLayout>
+#include <QDialog>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QTimer>
+#include "processwait.h"
+#include "appname.h"
+
+
+//------------------------------------------------------------------------
+
+QString ProcessWaitDialog::processErrorString( QProcess::ProcessError err)
+{
+ switch (err)
+ {
+ case QProcess::FailedToStart:
+ return QString(tr("Process failed to start"));
+ break;
+ case QProcess::Crashed:
+ return QString(tr("Process crashed"));
+ break;
+ case QProcess::Timedout:
+ return QString(tr("Process timedout"));
+ break;
+ case QProcess::WriteError:
+ return QString(tr("Error while trying to write to process"));
+ break;
+ case QProcess::ReadError:
+ return QString(tr("Error while trying to read from process"));
+ break;
+ case QProcess::UnknownError:
+ default:
+ return QString(tr("Unknown process error"));
+ }
+ return QString("");
+}
+//------------------------------------------------------------------------
+ProcessWaitDialog::ProcessWaitDialog(QWidget *parent, QProcess *process):
+ QDialog(parent), process(process)
+{
+ this->resize(400, 220);
+ this->setWindowTitle(QString(appName) + tr(" ... Process GPSBabel"));
+ QVBoxLayout *layout = new QVBoxLayout(this);
+
+ textEdit = new QPlainTextEdit(this);
+ textEdit->setReadOnly(true);
+ layout->addWidget(textEdit);
+
+ progressBar = new QProgressBar(this);
+ progressBar->setTextVisible(false);
+ layout->addWidget(progressBar);
+
+ buttonBox = new QDialogButtonBox(this);
+ buttonBox->setOrientation(Qt::Horizontal);
+ buttonBox->setStandardButtons(QDialogButtonBox::Abort);
+ QPushButton* btn = buttonBox->button(QDialogButtonBox::Abort);
+ btn->setText(tr("Stop Process"));
+ layout->addWidget(buttonBox);
+
+ connect(process, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT (errorX(QProcess::ProcessError)));
+ connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT (finishedX(int, QProcess::ExitStatus)));
+ connect(process, SIGNAL(readyReadStandardError()),
+ this, SLOT (readyReadStandardErrorX()));
+ connect(process, SIGNAL(readyReadStandardOutput()),
+ this, SLOT (readyReadStandardOutputX()));
+ connect(btn, SIGNAL(clicked()),
+ this, SLOT (stopClickedX()));
+ estatus = QProcess::CrashExit; // Assume all errors are crashes for now.
+
+ bufferedOut = "";
+
+ //
+ for (int i=0; i<=100; i+=2)
+ progressVals.push_back(i);
+ for (int i=98; i>0; i-=2)
+ progressVals.push_back(i);
+ progressIndex = progressVals.size()/2;
+
+ timer = new QTimer(this);
+ timer->setInterval(100);
+ timer->setSingleShot(false);
+ connect(timer, SIGNAL(timeout()), this, SLOT(timeoutX()));
+ stopCount = -1;
+ timer->start();
+ errorString = "";
+
+}
+
+//------------------------------------------------------------------------
+ProcessWaitDialog::~ProcessWaitDialog()
+{
+};
+//------------------------------------------------------------------------
+bool ProcessWaitDialog::getExitedNormally()
+{
+ return (errorString.length() == 0);
+};
+
+//------------------------------------------------------------------------
+QString ProcessWaitDialog::getErrorString()
+{
+ return errorString;
+};
+
+//------------------------------------------------------------------------
+int ProcessWaitDialog::getExitCode()
+{
+ return ecode;
+};
+
+//------------------------------------------------------------------------
+void ProcessWaitDialog::stopClickedX()
+{
+ process->terminate();
+};
+//------------------------------------------------------------------------
+void ProcessWaitDialog::timeoutX()
+{
+ progressIndex++;
+ int idx = progressIndex % progressVals.size();
+ progressBar->setValue(progressVals[idx]);
+ if (stopCount >=0)
+ stopCount++;
+ if (stopCount > 150) {
+ process->kill();
+ errorString = QString(tr("Process did not terminate successfully"));
+ timer->stop();
+ accept();
+ }
+};
+
+//------------------------------------------------------------------------
+void ProcessWaitDialog::errorX(QProcess::ProcessError err)
+{
+ errorString = processErrorString(err);
+ timer->stop();
+ accept();
+};
+
+//------------------------------------------------------------------------
+void ProcessWaitDialog::finishedX(int exitCode, QProcess::ExitStatus es)
+{
+ ecode = exitCode;
+ if (es == QProcess::CrashExit)
+ errorString = QString(tr("Process crashed whle running"));
+ timer->stop();
+ accept();
+};
+
+
+//------------------------------------------------------------------------
+// appendPlainText automatically puts in a new line with every call. That's
+// why you have to buffer it, and only append when we get a real newline.
+//
+void ProcessWaitDialog::appendToText(const char *ptr)
+{
+ outputString += QString(ptr);
+ for (const char *cptr = ptr; *cptr; cptr++) {
+ if (*cptr == '\r')
+ continue;
+ if (*cptr == '\n') {
+ textEdit->appendPlainText(QString::fromStdString(bufferedOut));
+ bufferedOut = "";
+ continue;
+ }
+ bufferedOut += *cptr;
+ }
+}
+
+
+//------------------------------------------------------------------------
+void ProcessWaitDialog::readyReadStandardErrorX()
+{
+ QByteArray d = process->readAllStandardError();
+ appendToText(d.data());
+};
+
+//------------------------------------------------------------------------
+void ProcessWaitDialog::readyReadStandardOutputX()
+ {
+ QByteArray d = process->readAllStandardOutput();
+ appendToText(d.data());
+};
+
+void ProcessWaitDialog::closeEvent(QCloseEvent *event)
+{
+ event->ignore();
+};
+++ /dev/null
-// -*- c++ -*-
-// $Id: processwait.cpp,v 1.3 2009-08-28 17:08:55 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-//------------------------------------------------------------------------
-#include <QProcess>
-#include <QStringList>
-#include <QPlainTextEdit>
-#include <QDialogButtonBox>
-#include <QVBoxLayout>
-#include <QDialog>
-#include <QProgressBar>
-#include <QPushButton>
-#include <QTimer>
-#include "processwait.h"
-#include "appname.h"
-
-
-//------------------------------------------------------------------------
-
-QString ProcessWaitDialog::processErrorString( QProcess::ProcessError err)
-{
- switch (err)
- {
- case QProcess::FailedToStart:
- return QString(tr("Process failed to start"));
- break;
- case QProcess::Crashed:
- return QString(tr("Process crashed"));
- break;
- case QProcess::Timedout:
- return QString(tr("Process timedout"));
- break;
- case QProcess::WriteError:
- return QString(tr("Error while trying to write to process"));
- break;
- case QProcess::ReadError:
- return QString(tr("Error while trying to read from process"));
- break;
- case QProcess::UnknownError:
- default:
- return QString(tr("Unknown process error"));
- }
- return QString("");
-}
-//------------------------------------------------------------------------
-ProcessWaitDialog::ProcessWaitDialog(QWidget *parent, QProcess *process):
- QDialog(parent), process(process)
-{
- this->resize(400, 220);
- this->setWindowTitle(QString(appName) + tr(" ... Process GPSBabel"));
- QVBoxLayout *layout = new QVBoxLayout(this);
-
- textEdit = new QPlainTextEdit(this);
- textEdit->setReadOnly(true);
- layout->addWidget(textEdit);
-
- progressBar = new QProgressBar(this);
- progressBar->setTextVisible(false);
- layout->addWidget(progressBar);
-
- buttonBox = new QDialogButtonBox(this);
- buttonBox->setOrientation(Qt::Horizontal);
- buttonBox->setStandardButtons(QDialogButtonBox::Abort);
- QPushButton* btn = buttonBox->button(QDialogButtonBox::Abort);
- btn->setText(tr("Stop Process"));
- layout->addWidget(buttonBox);
-
- connect(process, SIGNAL(error(QProcess::ProcessError)),
- this, SLOT (errorX(QProcess::ProcessError)));
- connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
- this, SLOT (finishedX(int, QProcess::ExitStatus)));
- connect(process, SIGNAL(readyReadStandardError()),
- this, SLOT (readyReadStandardErrorX()));
- connect(process, SIGNAL(readyReadStandardOutput()),
- this, SLOT (readyReadStandardOutputX()));
- connect(btn, SIGNAL(clicked()),
- this, SLOT (stopClickedX()));
- estatus = QProcess::CrashExit; // Assume all errors are crashes for now.
-
- bufferedOut = "";
-
- //
- for (int i=0; i<=100; i+=2)
- progressVals.push_back(i);
- for (int i=98; i>0; i-=2)
- progressVals.push_back(i);
- progressIndex = progressVals.size()/2;
-
- timer = new QTimer(this);
- timer->setInterval(100);
- timer->setSingleShot(false);
- connect(timer, SIGNAL(timeout()), this, SLOT(timeoutX()));
- stopCount = -1;
- timer->start();
- errorString = "";
-
-}
-
-//------------------------------------------------------------------------
-ProcessWaitDialog::~ProcessWaitDialog()
-{
-};
-//------------------------------------------------------------------------
-bool ProcessWaitDialog::getExitedNormally()
-{
- return (errorString.length() == 0);
-};
-
-//------------------------------------------------------------------------
-QString ProcessWaitDialog::getErrorString()
-{
- return errorString;
-};
-
-//------------------------------------------------------------------------
-int ProcessWaitDialog::getExitCode()
-{
- return ecode;
-};
-
-//------------------------------------------------------------------------
-void ProcessWaitDialog::stopClickedX()
-{
- process->terminate();
-};
-//------------------------------------------------------------------------
-void ProcessWaitDialog::timeoutX()
-{
- progressIndex++;
- int idx = progressIndex % progressVals.size();
- progressBar->setValue(progressVals[idx]);
- if (stopCount >=0)
- stopCount++;
- if (stopCount > 150) {
- process->kill();
- errorString = QString(tr("Process did not terminate successfully"));
- timer->stop();
- accept();
- }
-};
-
-//------------------------------------------------------------------------
-void ProcessWaitDialog::errorX(QProcess::ProcessError err)
-{
- errorString = processErrorString(err);
- timer->stop();
- accept();
-};
-
-//------------------------------------------------------------------------
-void ProcessWaitDialog::finishedX(int exitCode, QProcess::ExitStatus es)
-{
- ecode = exitCode;
- if (es == QProcess::CrashExit)
- errorString = QString(tr("Process crashed whle running"));
- timer->stop();
- accept();
-};
-
-
-//------------------------------------------------------------------------
-// appendPlainText automatically puts in a new line with every call. That's
-// why you have to buffer it, and only append when we get a real newline.
-//
-void ProcessWaitDialog::appendToText(const char *ptr)
-{
- outputString += QString(ptr);
- for (const char *cptr = ptr; *cptr; cptr++) {
- if (*cptr == '\r')
- continue;
- if (*cptr == '\n') {
- textEdit->appendPlainText(QString::fromStdString(bufferedOut));
- bufferedOut = "";
- continue;
- }
- bufferedOut += *cptr;
- }
-}
-
-
-//------------------------------------------------------------------------
-void ProcessWaitDialog::readyReadStandardErrorX()
-{
- QByteArray d = process->readAllStandardError();
- appendToText(d.data());
-};
-
-//------------------------------------------------------------------------
-void ProcessWaitDialog::readyReadStandardOutputX()
- {
- QByteArray d = process->readAllStandardOutput();
- appendToText(d.data());
-};
-
-void ProcessWaitDialog::closeEvent(QCloseEvent *event)
-{
- event->ignore();
-};
--- /dev/null
+// Borrowed liberally (as allowed by license) from
+// http://developer.apple.com/samplecode/SerialPortSample/index.html
+// This really is a slash-and-burn; no attempt was to make it very "C++-iike"
+
+// Apple's copyright blob:
+/*
+ Copyright: © Copyright 2000-2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <paths.h>
+#include <termios.h>
+#include <sysexits.h>
+#include <sys/param.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <time.h>
+#include <AvailabilityMacros.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/serial/IOSerialKeys.h>
+#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
+#include <IOKit/serial/ioss.h>
+#endif
+#include <IOKit/IOBSD.h>
+
+#include "mainwindow.h"
+
+// Function prototypes
+static kern_return_t FindModems(io_iterator_t *matchingServices);
+// static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize);
+// static int OpenSerialPort(const char *bsdPath);
+
+// Returns an iterator across all known modems. Caller is responsible for
+// releasing the iterator when iteration is complete.
+static kern_return_t FindModems(io_iterator_t *matchingServices)
+{
+ kern_return_t kernResult;
+ CFMutableDictionaryRef classesToMatch;
+
+/*! @function IOServiceMatching
+ @abstract Create a matching dictionary that specifies an IOService class match.
+ @discussion A very common matching criteria for IOService is based on its class. IOServiceMatching will create a matching dictionary that specifies any IOService of a class, or its subclasses. The class is specified by C-string name.
+ @param name The class name, as a const C-string. Class matching is successful on IOService's of this class or any subclass.
+ @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */
+
+ // Serial devices are instances of class IOSerialBSDClient
+ classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
+ if (classesToMatch == NULL)
+ {
+ printf("IOServiceMatching returned a NULL dictionary.\n");
+ }
+ else {
+/*!
+ @function CFDictionarySetValue
+ Sets the value of the key in the dictionary.
+ @param theDict The dictionary to which the value is to be set. If this
+ parameter is not a valid mutable CFDictionary, the behavior is
+ undefined. If the dictionary is a fixed-capacity dictionary and
+ it is full before this operation, and the key does not exist in
+ the dictionary, the behavior is undefined.
+ @param key The key of the value to set into the dictionary. If a key
+ which matches this key is already present in the dictionary, only
+ the value is changed ("add if absent, replace if present"). If
+ no key matches the given key, the key-value pair is added to the
+ dictionary. If added, the key is retained by the dictionary,
+ using the retain callback provided
+ when the dictionary was created. If the key is not of the sort
+ expected by the key retain callback, the behavior is undefined.
+ @param value The value to add to or replace into the dictionary. The value
+ is retained by the dictionary using the retain callback provided
+ when the dictionary was created, and the previous value if any is
+ released. If the value is not of the sort expected by the
+ retain or release callbacks, the behavior is undefined.
+*/
+// CFDictionarySetValue(classesToMatch,
+// CFSTR(kIOSerialBSDTypeKey),
+// CFSTR(kIOSerialBSDModemType));
+
+ // Each serial device object has a property with key
+ // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes,
+ // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with the
+ // matching by changing the last parameter in the above call to CFDictionarySetValue.
+
+ // As shipped, this sample is only interested in modems,
+ // so add this property to the CFDictionary we're matching on.
+ // This will find devices that advertise themselves as modems,
+ // such as built-in and USB modems. However, this match won't find serial modems.
+ }
+
+ /*! @function IOServiceGetMatchingServices
+ @abstract Look up registered IOService objects that match a matching dictionary.
+ @discussion This is the preferred method of finding IOService objects currently registered by IOKit. IOServiceAddNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up.
+ @param masterPort The master port obtained from IOMasterPort().
+ @param matching A CF dictionary containing matching information, of which one reference is consumed by this function. IOKitLib can contruct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOOpenFirmwarePathMatching.
+ @param existing An iterator handle is returned on success, and should be released by the caller when the iteration is finished.
+ @result A kern_return_t error code. */
+
+ kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices);
+ if (KERN_SUCCESS != kernResult)
+ {
+ printf("IOServiceGetMatchingServices returned %d\n", kernResult);
+ goto exit;
+ }
+
+exit:
+ return kernResult;
+}
+
+// Given an iterator across a set of modems, return the BSD path to the first one.
+// If no modems are found the path name is set to an empty string.
+static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize, QComboBox *box)
+{
+ io_object_t modemService;
+ kern_return_t kernResult = KERN_FAILURE;
+ Boolean modemFound = false;
+
+ // Initialize the returned path
+ *bsdPath = '\0';
+
+ // Iterate across all modems found. In this example, we bail after finding the first modem.
+
+ while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound)
+ {
+ CFTypeRef bsdPathAsCFString;
+
+ // Get the callout device's path (/dev/cu.xxxxx). The callout device should almost always be
+ // used: the dialin device (/dev/tty.xxxxx) would be used when monitoring a serial port for
+ // incoming calls, e.g. a fax listener.
+
+ bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService,
+ CFSTR(kIOCalloutDeviceKey),
+ kCFAllocatorDefault,
+ 0);
+ if (bsdPathAsCFString)
+ {
+ Boolean result;
+
+ // Convert the path from a CFString to a C (NUL-terminated) string for use
+ // with the POSIX open() call.
+
+ result = CFStringGetCString((const __CFString*) bsdPathAsCFString,
+ bsdPath,
+ maxPathSize,
+ kCFStringEncodingUTF8);
+ CFRelease(bsdPathAsCFString);
+
+ if (result) {
+ box->addItem(bsdPath);
+ }
+ }
+
+ // Release the io_service_t now that we are done with it.
+
+// (void) IOObjectRelease(modemService);
+ }
+
+ return kernResult;
+}
+
+#include "mainwindow.h"
+void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
+{
+ kern_return_t kernResult;
+ io_iterator_t serialPortIterator;
+ char bsdPath[MAXPATHLEN];
+
+ kernResult = FindModems(&serialPortIterator);
+ kernResult = GetModemPath(serialPortIterator, bsdPath, sizeof(bsdPath), box);
+
+}
+++ /dev/null
-// Borrowed liberally (as allowed by license) from
-// http://developer.apple.com/samplecode/SerialPortSample/index.html
-// This really is a slash-and-burn; no attempt was to make it very "C++-iike"
-
-// Apple's copyright blob:
-/*
- Copyright: © Copyright 2000-2005 Apple Computer, Inc. All rights reserved.
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- ("Apple") in consideration of your agreement to the following terms, and your
- use, installation, modification or redistribution of this Apple software
- constitutes acceptance of these terms. If you do not agree with these terms,
- please do not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject
- to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
- copyrights in this original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or without
- modifications, in source and/or binary forms; provided that if you redistribute
- the Apple Software in its entirety and without modifications, you must retain
- this notice and the following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks or logos of
- Apple Computer, Inc. may be used to endorse or promote products derived from the
- Apple Software without specific prior written permission from Apple. Except as
- expressly stated in this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any patent rights that
- may be infringed by your derivative works or by other works in which the Apple
- Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*/
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <paths.h>
-#include <termios.h>
-#include <sysexits.h>
-#include <sys/param.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <time.h>
-#include <AvailabilityMacros.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/serial/IOSerialKeys.h>
-#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3)
-#include <IOKit/serial/ioss.h>
-#endif
-#include <IOKit/IOBSD.h>
-
-#include "mainwindow.h"
-
-// Function prototypes
-static kern_return_t FindModems(io_iterator_t *matchingServices);
-// static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize);
-// static int OpenSerialPort(const char *bsdPath);
-
-// Returns an iterator across all known modems. Caller is responsible for
-// releasing the iterator when iteration is complete.
-static kern_return_t FindModems(io_iterator_t *matchingServices)
-{
- kern_return_t kernResult;
- CFMutableDictionaryRef classesToMatch;
-
-/*! @function IOServiceMatching
- @abstract Create a matching dictionary that specifies an IOService class match.
- @discussion A very common matching criteria for IOService is based on its class. IOServiceMatching will create a matching dictionary that specifies any IOService of a class, or its subclasses. The class is specified by C-string name.
- @param name The class name, as a const C-string. Class matching is successful on IOService's of this class or any subclass.
- @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */
-
- // Serial devices are instances of class IOSerialBSDClient
- classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue);
- if (classesToMatch == NULL)
- {
- printf("IOServiceMatching returned a NULL dictionary.\n");
- }
- else {
-/*!
- @function CFDictionarySetValue
- Sets the value of the key in the dictionary.
- @param theDict The dictionary to which the value is to be set. If this
- parameter is not a valid mutable CFDictionary, the behavior is
- undefined. If the dictionary is a fixed-capacity dictionary and
- it is full before this operation, and the key does not exist in
- the dictionary, the behavior is undefined.
- @param key The key of the value to set into the dictionary. If a key
- which matches this key is already present in the dictionary, only
- the value is changed ("add if absent, replace if present"). If
- no key matches the given key, the key-value pair is added to the
- dictionary. If added, the key is retained by the dictionary,
- using the retain callback provided
- when the dictionary was created. If the key is not of the sort
- expected by the key retain callback, the behavior is undefined.
- @param value The value to add to or replace into the dictionary. The value
- is retained by the dictionary using the retain callback provided
- when the dictionary was created, and the previous value if any is
- released. If the value is not of the sort expected by the
- retain or release callbacks, the behavior is undefined.
-*/
-// CFDictionarySetValue(classesToMatch,
-// CFSTR(kIOSerialBSDTypeKey),
-// CFSTR(kIOSerialBSDModemType));
-
- // Each serial device object has a property with key
- // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes,
- // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with the
- // matching by changing the last parameter in the above call to CFDictionarySetValue.
-
- // As shipped, this sample is only interested in modems,
- // so add this property to the CFDictionary we're matching on.
- // This will find devices that advertise themselves as modems,
- // such as built-in and USB modems. However, this match won't find serial modems.
- }
-
- /*! @function IOServiceGetMatchingServices
- @abstract Look up registered IOService objects that match a matching dictionary.
- @discussion This is the preferred method of finding IOService objects currently registered by IOKit. IOServiceAddNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up.
- @param masterPort The master port obtained from IOMasterPort().
- @param matching A CF dictionary containing matching information, of which one reference is consumed by this function. IOKitLib can contruct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOOpenFirmwarePathMatching.
- @param existing An iterator handle is returned on success, and should be released by the caller when the iteration is finished.
- @result A kern_return_t error code. */
-
- kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices);
- if (KERN_SUCCESS != kernResult)
- {
- printf("IOServiceGetMatchingServices returned %d\n", kernResult);
- goto exit;
- }
-
-exit:
- return kernResult;
-}
-
-// Given an iterator across a set of modems, return the BSD path to the first one.
-// If no modems are found the path name is set to an empty string.
-static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize, QComboBox *box)
-{
- io_object_t modemService;
- kern_return_t kernResult = KERN_FAILURE;
- Boolean modemFound = false;
-
- // Initialize the returned path
- *bsdPath = '\0';
-
- // Iterate across all modems found. In this example, we bail after finding the first modem.
-
- while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound)
- {
- CFTypeRef bsdPathAsCFString;
-
- // Get the callout device's path (/dev/cu.xxxxx). The callout device should almost always be
- // used: the dialin device (/dev/tty.xxxxx) would be used when monitoring a serial port for
- // incoming calls, e.g. a fax listener.
-
- bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService,
- CFSTR(kIOCalloutDeviceKey),
- kCFAllocatorDefault,
- 0);
- if (bsdPathAsCFString)
- {
- Boolean result;
-
- // Convert the path from a CFString to a C (NUL-terminated) string for use
- // with the POSIX open() call.
-
- result = CFStringGetCString((const __CFString*) bsdPathAsCFString,
- bsdPath,
- maxPathSize,
- kCFStringEncodingUTF8);
- CFRelease(bsdPathAsCFString);
-
- if (result) {
- box->addItem(bsdPath);
- }
- }
-
- // Release the io_service_t now that we are done with it.
-
-// (void) IOObjectRelease(modemService);
- }
-
- return kernResult;
-}
-
-#include "mainwindow.h"
-void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
-{
- kern_return_t kernResult;
- io_iterator_t serialPortIterator;
- char bsdPath[MAXPATHLEN];
-
- kernResult = FindModems(&serialPortIterator);
- kernResult = GetModemPath(serialPortIterator, bsdPath, sizeof(bsdPath), box);
-
-}
--- /dev/null
+// $Id: serial_unix.cpp,v 1.2 2010-02-13 23:25:23 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+#include "mainwindow.h"
+#if !defined (Q_OS_MAC) // FIXME: find a better way to hide this on Mac.
+
+static const char *deviceNames[] = {
+ "/dev/ttyS0",
+ "/dev/ttyS1",
+ "/dev/ttyS2",
+ "/dev/ttyS3",
+ "/dev/ttyUSB0",
+ "/dev/rfcomm0",
+ 0
+};
+
+void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
+{
+ for (int i=0; deviceNames[i]; i++) {
+ box->addItem(deviceNames[i]);
+ }
+}
+#endif
+++ /dev/null
-// $Id: serial_unix.cpp,v 1.2 2010-02-13 23:25:23 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-#include "mainwindow.h"
-#if !defined (Q_OS_MAC) // FIXME: find a better way to hide this on Mac.
-
-static const char *deviceNames[] = {
- "/dev/ttyS0",
- "/dev/ttyS1",
- "/dev/ttyS2",
- "/dev/ttyS3",
- "/dev/ttyUSB0",
- "/dev/rfcomm0",
- 0
-};
-
-void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
-{
- for (int i=0; deviceNames[i]; i++) {
- box->addItem(deviceNames[i]);
- }
-}
-#endif
--- /dev/null
+// $Id: serial_win.cpp,v 1.3 2010-06-21 02:35:06 robertl Exp $
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+
+#include "mainwindow.h"
+
+#if 0 // Does not require Windows 2000
+
+static const char *deviceNames[] = {
+ "com1:",
+ "com2:",
+ "com3:",
+ "com4:",
+ 0
+};
+
+void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
+{
+ for (int i=0; deviceNames[i]; i++) {
+ box->addItem(deviceNames[i]);
+ }
+}
+
+#else // This code assumes Windows 2000 or later
+
+// Uses QueryDosDevice(), Minimum supported: Windows 2000 Professional/Server
+#include <Windows.h>
+#include <stdio.h>
+
+void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
+{
+ char DevList[64*1024-1]; // a single byte more, and certain versions of windows
+ // always return QueryDosDevice()==0 && GetLastError()==ERROR_MORE_DATA.
+ // see http://support.microsoft.com/kb/931305
+ // Get a list of all existing MS-DOS device names. Stores one or more asciiz strings followed by an extra null.
+ DWORD res = QueryDosDeviceA(NULL, DevList, sizeof(DevList));
+ if (res == 0)
+ {
+ DWORD err = GetLastError(); // could check for ERROR_INSUFFICIENT_BUFFER, and retry with a larger buffer.
+ // but DevList is already at the maximum size it can be without running into kb 931305.
+ // FIXME: This shold be a QMessageBox::warning() - RJL
+ // fprintf(stderr,"QueryDosDevice() failed with %d. GetLastError()==%d.\n", res, err);
+ (void) err;
+ return;
+ }
+
+ for (char *p=DevList; *p;) {
+ int len = strlen(p);
+ if (strncmp(p,"COM",3)==0)
+ box->addItem((PCHAR)p);
+ p += len+1; // +1 to also skip the null character of each string
+ }
+}
+
+#endif
+++ /dev/null
-// $Id: serial_win.cpp,v 1.3 2010-06-21 02:35:06 robertl Exp $
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2009 S. Khai Mong <khai@mangrai.com>.
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-
-#include "mainwindow.h"
-
-#if 0 // Does not require Windows 2000
-
-static const char *deviceNames[] = {
- "com1:",
- "com2:",
- "com3:",
- "com4:",
- 0
-};
-
-void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
-{
- for (int i=0; deviceNames[i]; i++) {
- box->addItem(deviceNames[i]);
- }
-}
-
-#else // This code assumes Windows 2000 or later
-
-// Uses QueryDosDevice(), Minimum supported: Windows 2000 Professional/Server
-#include <Windows.h>
-#include <stdio.h>
-
-void MainWindow::osLoadDeviceNameCombos(QComboBox *box)
-{
- char DevList[64*1024-1]; // a single byte more, and certain versions of windows
- // always return QueryDosDevice()==0 && GetLastError()==ERROR_MORE_DATA.
- // see http://support.microsoft.com/kb/931305
- // Get a list of all existing MS-DOS device names. Stores one or more asciiz strings followed by an extra null.
- DWORD res = QueryDosDeviceA(NULL, DevList, sizeof(DevList));
- if (res == 0)
- {
- DWORD err = GetLastError(); // could check for ERROR_INSUFFICIENT_BUFFER, and retry with a larger buffer.
- // but DevList is already at the maximum size it can be without running into kb 931305.
- // FIXME: This shold be a QMessageBox::warning() - RJL
- // fprintf(stderr,"QueryDosDevice() failed with %d. GetLastError()==%d.\n", res, err);
- (void) err;
- return;
- }
-
- for (char *p=DevList; *p;) {
- int len = strlen(p);
- if (strncmp(p,"COM",3)==0)
- box->addItem((PCHAR)p);
- p += len+1; // +1 to also skip the null character of each string
- }
-}
-
-#endif
--- /dev/null
+// -*- C++ -*-
+// $Id: upgrade.cpp,v 1.26 2010-06-19 23:59:06 robertl Exp $
+/*
+ Copyright (C) 2009, 2010 Robert Lipe, robertlipe@gpsbabel.org
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+
+#include "babeldata.h"
+#include "format.h"
+#include "upgrade.h"
+#include "../gbversion.h"
+#if HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#if HAVE_UNAME
+#include <sys/utsname.h>
+#endif // HAVE_UNAME
+
+#include <QHttp>
+#include <QMessageBox>
+#include <QDesktopServices>
+#include <QDomDocument>
+#include <QLocale>
+#include <QSysInfo>
+#include <QUrl>
+#include <stdio.h>
+
+#if 0
+static const bool testing = true;
+#else
+static const bool testing = false;
+#endif
+
+UpgradeCheck::UpgradeCheck(QWidget *parent, QList<Format> &formatList,
+ BabelData& bd) :
+ QObject(parent),
+ http(0),
+ formatList_(formatList),
+ updateStatus_(updateUnknown),
+ bd_(bd)
+{
+}
+
+UpgradeCheck::~UpgradeCheck()
+{
+ if (http) {
+ http->clearPendingRequests();
+ http->abort();
+ delete http;
+ http = 0;
+ }
+}
+
+bool UpgradeCheck::isTestMode()
+{
+ return testing;
+}
+
+QString UpgradeCheck::getOsName(void)
+{
+ // Do not translate these strings.
+#if defined (Q_OS_LINUX)
+ return "Linux";
+#elif defined (Q_OS_MAC)
+ return "Mac";
+#elif defined (Q_OS_WIN)
+ return "Windows";
+#else
+ return "Unknown";
+#endif
+
+}
+// See http://doc.trolltech.com/4.5/qsysinfo.html to interpret results
+QString UpgradeCheck::getOsVersion()
+{
+#if defined (Q_OS_MAC)
+ switch (QSysInfo::MacintoshVersion) {
+ case QSysInfo::MV_10_3: return "10.3"; break;
+ case QSysInfo::MV_10_4: return "10.4"; break;
+ case QSysInfo::MV_10_5: return "10.5"; break;
+ case QSysInfo::MV_10_6: return "10.6"; break;
+ case QSysInfo::MV_10_7: return "10.7"; break;
+ //case QSysInfo::MV_10_8: return "10.8"; break;
+ default:
+ if (QSysInfo::MacintoshVersion == 10) {
+ return "10.8";
+ break;
+ }
+ return QString("Unknown Mac %1").arg(QSysInfo::MacintoshVersion);
+ };
+#elif defined (Q_OS_WIN)
+
+ switch (QSysInfo::WindowsVersion) {
+ // Wildly improbable...
+ case QSysInfo::WV_95: return "95"; break;
+ case QSysInfo::WV_98: return "98"; break;
+ case QSysInfo::WV_Me: return "Me"; break;
+
+ case QSysInfo::WV_4_0: return "NT 4"; break;
+ case QSysInfo::WV_5_0: return "2000"; break;
+ case QSysInfo::WV_5_1: return "XP"; break;
+ case QSysInfo::WV_5_2: return "2003"; break;
+ case QSysInfo::WV_6_0: return "Vista"; break;
+ case QSysInfo::WV_6_1: return "7"; break;
+ default:
+ return "Windows/Unknown";
+ }
+#endif
+ // FIXME: find something appropriately clever to do for Linux, etc. here.
+ return "Unknown";
+}
+
+
+UpgradeCheck::updateStatus UpgradeCheck::checkForUpgrade(
+ const QString ¤tVersionIn,
+ const QDateTime &lastCheckTime,
+ bool allowBeta)
+{
+ currentVersion = currentVersionIn;
+ currentVersion.remove("GPSBabel Version ");
+
+ QDateTime soonestCheckTime = lastCheckTime.addDays(1);
+ if (!testing && QDateTime::currentDateTime() < soonestCheckTime) {
+ // Not time to check yet.
+ return UpgradeCheck::updateUnknown;
+ }
+
+ http = new QHttp;
+
+ connect(http, SIGNAL(requestFinished(int, bool)),
+ this, SLOT(httpRequestFinished(int, bool)));
+ connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
+ this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
+
+ QHttpRequestHeader header("POST", "/upgrade_check.html");
+
+ const QString host("www.gpsbabel.org" );
+ header.setValue("Host", host);
+
+ header.setContentType("application/x-www-form-urlencoded");
+ QLocale locale;
+
+ QString args = "current_version=" + currentVersion;
+ args += "¤t_gui_version=" VERSION;
+ args += "&installation=" + bd_.installationUuid;
+ args += "&os=" + getOsName();
+#if HAVE_UNAME
+ struct utsname utsname;
+ if (0 == uname(&utsname)) {
+ args += "&cpu=" + QString(utsname.machine);
+ }
+#endif
+
+ args += "&os_ver=" + getOsVersion();
+ args += QString("&beta_ok=%1").arg(allowBeta);
+ args += "&lang=" + QLocale::languageToString(locale.language());
+ args += "&last_checkin=" + lastCheckTime.toString(Qt::ISODate);
+ args += QString("&ugcb=%1").arg(bd_.upgradeCallbacks);
+ args += QString("&ugdec=%1").arg(bd_.upgradeDeclines);
+ args += QString("&ugacc=%1").arg(bd_.upgradeAccept);
+ args += QString("&ugoff=%1").arg(bd_.upgradeOffers);
+ args += QString("&ugerr=%1").arg(bd_.upgradeErrors);
+ args += QString("&rc=%1").arg(bd_.runCount);
+
+ int j = 0;
+
+ for (int i = 0; i < formatList_.size(); i++) {
+ int rc = formatList_[i].getReadUseCount();
+ int wc = formatList_[i].getWriteUseCount();
+ QString formatName = formatList_[i].getName();
+ if (rc)
+ args += QString("&uc%1=rd/%2/%3").arg(j++).arg(formatName).arg(rc);
+ if (wc)
+ args += QString("&uc%1=wr/%2/%3").arg(j++).arg(formatName).arg(wc);
+ }
+ if (j && bd_.reportStatistics)
+ args += QString("&uc=%1").arg(j);
+
+ if (false && testing)
+ fprintf(stderr, "Posting %s\n", qPrintable(args));
+
+ http->setHost(host, 80);
+ httpRequestId = http->request(header, args.toUtf8());
+
+ return UpgradeCheck::updateUnknown;
+}
+
+void UpgradeCheck::readResponseHeader(const QHttpResponseHeader &responseHeader)
+{
+ switch (responseHeader.statusCode()) {
+ case 200: // Ok
+ case 301: // Moved Permanently
+ case 302: // Found
+ case 303: // See Other
+ case 307: // Temporary Redirect
+ // these are not error conditions
+ break;
+
+ default:
+ QMessageBox::information(0, tr("HTTP"),
+ tr("Download failed: %1.")
+ .arg(responseHeader.reasonPhrase()));
+ httpRequestAborted = true;
+ http->abort();
+ }
+}
+
+void UpgradeCheck::httpRequestFinished(int requestId, bool error)
+{
+
+ if (http == 0 || error) {
+ bd_.upgradeErrors++;
+ return;
+ }
+
+ // This is not an error state; it's just the internal state of Qt's network
+ // stack flailing around.
+ if (requestId != httpRequestId) {
+ return;
+ }
+
+ bd_.upgradeCallbacks++;
+ QString oresponse(http->readAll());
+
+ QDomDocument document;
+ int line = -1;
+ QString error_text;
+ // This shouldn't ever be seen by a user.
+ if (!document.setContent(oresponse, &error_text, &line)) {
+ QMessageBox::critical(0, tr("Error"),
+ tr("Invalid return data at line %1: %2.")
+ .arg(line)
+ .arg( error_text));
+ bd_.upgradeErrors++;
+ return;
+ }
+
+ QString response;
+ QString upgradeText;
+
+ if (testing)
+ currentVersion = "1.3.1"; // for testing
+
+ bool allowBeta = true; // TODO: come from prefs or current version...
+
+ QDomNodeList upgrades = document.elementsByTagName("update");
+ QUrl downloadUrl;
+ updateStatus_ = updateCurrent; // Current until proven guilty.
+
+ for (unsigned int i = 0; i < upgrades.length(); i++) {
+ QDomNode upgradeNode = upgrades.item(i);
+ QDomElement upgrade = upgradeNode.toElement();
+
+ QString updateVersion = upgrade.attribute("version");
+ if (upgrade.attribute("downloadURL").isEmpty()) {
+ downloadUrl = "http://www.gpsbabel.org/download.html";
+ } else {
+ downloadUrl = upgrade.attribute("downloadURL");
+ }
+ bool updateIsBeta = upgrade.attribute("type") == "beta";
+ bool updateIsMajor = upgrade.attribute("type") == "major";
+ bool updateIsMinor = upgrade.attribute("type") == "minor";
+
+ bool updateCandidate = updateIsMajor || updateIsMinor || (updateIsBeta && allowBeta);
+ upgradeText = upgrade.firstChildElement("overview").text();
+ // String compare, not a numeric one. Server will return "best first".
+ if((updateVersion > currentVersion) && updateCandidate) {
+ bd_.upgradeOffers++;
+ updateStatus_ = updateNeeded;
+ response = tr("A new version of GPSBabel is available.<br />"
+ "Your version is %1 <br />"
+ "The latest version is %2")
+ .arg(currentVersion)
+ .arg(updateVersion);
+ break;
+ }
+ }
+
+ if (response.length()) {
+ QMessageBox information;
+ information.setWindowTitle(tr("Upgrade"));
+
+ information.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ information.setDefaultButton(QMessageBox::Yes);
+ information.setText(response);
+
+ information.setInformativeText(tr("Do you wish to download an upgrade?"));
+ information.setDetailedText(upgradeText);
+
+ switch (information.exec()) {
+ case QMessageBox::Yes:
+ // downloadUrl.addQueryItem("os", getOsName());
+ QDesktopServices::openUrl(downloadUrl);
+ bd_.upgradeAccept++;
+ break;
+ default: ;
+ bd_.upgradeDeclines++;
+ }
+ }
+
+ upgradeWarningTime = QDateTime(QDateTime::currentDateTime());
+
+ for (int i = 0; i < formatList_.size(); i++) {
+ formatList_[i].zeroUseCounts();
+ }
+}
+++ /dev/null
-// -*- C++ -*-
-// $Id: upgrade.cpp,v 1.26 2010-06-19 23:59:06 robertl Exp $
-/*
- Copyright (C) 2009, 2010 Robert Lipe, robertlipe@gpsbabel.org
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
-
- */
-
-
-#include "babeldata.h"
-#include "format.h"
-#include "upgrade.h"
-#include "../gbversion.h"
-#if HAVE_CONFIG_H
-#include "../config.h"
-#endif
-
-#if HAVE_UNAME
-#include <sys/utsname.h>
-#endif // HAVE_UNAME
-
-#include <QHttp>
-#include <QMessageBox>
-#include <QDesktopServices>
-#include <QDomDocument>
-#include <QLocale>
-#include <QSysInfo>
-#include <QUrl>
-#include <stdio.h>
-
-#if 0
-static const bool testing = true;
-#else
-static const bool testing = false;
-#endif
-
-UpgradeCheck::UpgradeCheck(QWidget *parent, QList<Format> &formatList,
- BabelData& bd) :
- QObject(parent),
- http(0),
- formatList_(formatList),
- updateStatus_(updateUnknown),
- bd_(bd)
-{
-}
-
-UpgradeCheck::~UpgradeCheck()
-{
- if (http) {
- http->clearPendingRequests();
- http->abort();
- delete http;
- http = 0;
- }
-}
-
-bool UpgradeCheck::isTestMode()
-{
- return testing;
-}
-
-QString UpgradeCheck::getOsName(void)
-{
- // Do not translate these strings.
-#if defined (Q_OS_LINUX)
- return "Linux";
-#elif defined (Q_OS_MAC)
- return "Mac";
-#elif defined (Q_OS_WIN)
- return "Windows";
-#else
- return "Unknown";
-#endif
-
-}
-// See http://doc.trolltech.com/4.5/qsysinfo.html to interpret results
-QString UpgradeCheck::getOsVersion()
-{
-#if defined (Q_OS_MAC)
- switch (QSysInfo::MacintoshVersion) {
- case QSysInfo::MV_10_3: return "10.3"; break;
- case QSysInfo::MV_10_4: return "10.4"; break;
- case QSysInfo::MV_10_5: return "10.5"; break;
- case QSysInfo::MV_10_6: return "10.6"; break;
- case QSysInfo::MV_10_7: return "10.7"; break;
- //case QSysInfo::MV_10_8: return "10.8"; break;
- default:
- if (QSysInfo::MacintoshVersion == 10) {
- return "10.8";
- break;
- }
- return QString("Unknown Mac %1").arg(QSysInfo::MacintoshVersion);
- };
-#elif defined (Q_OS_WIN)
-
- switch (QSysInfo::WindowsVersion) {
- // Wildly improbable...
- case QSysInfo::WV_95: return "95"; break;
- case QSysInfo::WV_98: return "98"; break;
- case QSysInfo::WV_Me: return "Me"; break;
-
- case QSysInfo::WV_4_0: return "NT 4"; break;
- case QSysInfo::WV_5_0: return "2000"; break;
- case QSysInfo::WV_5_1: return "XP"; break;
- case QSysInfo::WV_5_2: return "2003"; break;
- case QSysInfo::WV_6_0: return "Vista"; break;
- case QSysInfo::WV_6_1: return "7"; break;
- default:
- return "Windows/Unknown";
- }
-#endif
- // FIXME: find something appropriately clever to do for Linux, etc. here.
- return "Unknown";
-}
-
-
-UpgradeCheck::updateStatus UpgradeCheck::checkForUpgrade(
- const QString ¤tVersionIn,
- const QDateTime &lastCheckTime,
- bool allowBeta)
-{
- currentVersion = currentVersionIn;
- currentVersion.remove("GPSBabel Version ");
-
- QDateTime soonestCheckTime = lastCheckTime.addDays(1);
- if (!testing && QDateTime::currentDateTime() < soonestCheckTime) {
- // Not time to check yet.
- return UpgradeCheck::updateUnknown;
- }
-
- http = new QHttp;
-
- connect(http, SIGNAL(requestFinished(int, bool)),
- this, SLOT(httpRequestFinished(int, bool)));
- connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
- this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
-
- QHttpRequestHeader header("POST", "/upgrade_check.html");
-
- const QString host("www.gpsbabel.org" );
- header.setValue("Host", host);
-
- header.setContentType("application/x-www-form-urlencoded");
- QLocale locale;
-
- QString args = "current_version=" + currentVersion;
- args += "¤t_gui_version=" VERSION;
- args += "&installation=" + bd_.installationUuid;
- args += "&os=" + getOsName();
-#if HAVE_UNAME
- struct utsname utsname;
- if (0 == uname(&utsname)) {
- args += "&cpu=" + QString(utsname.machine);
- }
-#endif
-
- args += "&os_ver=" + getOsVersion();
- args += QString("&beta_ok=%1").arg(allowBeta);
- args += "&lang=" + QLocale::languageToString(locale.language());
- args += "&last_checkin=" + lastCheckTime.toString(Qt::ISODate);
- args += QString("&ugcb=%1").arg(bd_.upgradeCallbacks);
- args += QString("&ugdec=%1").arg(bd_.upgradeDeclines);
- args += QString("&ugacc=%1").arg(bd_.upgradeAccept);
- args += QString("&ugoff=%1").arg(bd_.upgradeOffers);
- args += QString("&ugerr=%1").arg(bd_.upgradeErrors);
- args += QString("&rc=%1").arg(bd_.runCount);
-
- int j = 0;
-
- for (int i = 0; i < formatList_.size(); i++) {
- int rc = formatList_[i].getReadUseCount();
- int wc = formatList_[i].getWriteUseCount();
- QString formatName = formatList_[i].getName();
- if (rc)
- args += QString("&uc%1=rd/%2/%3").arg(j++).arg(formatName).arg(rc);
- if (wc)
- args += QString("&uc%1=wr/%2/%3").arg(j++).arg(formatName).arg(wc);
- }
- if (j && bd_.reportStatistics)
- args += QString("&uc=%1").arg(j);
-
- if (false && testing)
- fprintf(stderr, "Posting %s\n", qPrintable(args));
-
- http->setHost(host, 80);
- httpRequestId = http->request(header, args.toUtf8());
-
- return UpgradeCheck::updateUnknown;
-}
-
-void UpgradeCheck::readResponseHeader(const QHttpResponseHeader &responseHeader)
-{
- switch (responseHeader.statusCode()) {
- case 200: // Ok
- case 301: // Moved Permanently
- case 302: // Found
- case 303: // See Other
- case 307: // Temporary Redirect
- // these are not error conditions
- break;
-
- default:
- QMessageBox::information(0, tr("HTTP"),
- tr("Download failed: %1.")
- .arg(responseHeader.reasonPhrase()));
- httpRequestAborted = true;
- http->abort();
- }
-}
-
-void UpgradeCheck::httpRequestFinished(int requestId, bool error)
-{
-
- if (http == 0 || error) {
- bd_.upgradeErrors++;
- return;
- }
-
- // This is not an error state; it's just the internal state of Qt's network
- // stack flailing around.
- if (requestId != httpRequestId) {
- return;
- }
-
- bd_.upgradeCallbacks++;
- QString oresponse(http->readAll());
-
- QDomDocument document;
- int line = -1;
- QString error_text;
- // This shouldn't ever be seen by a user.
- if (!document.setContent(oresponse, &error_text, &line)) {
- QMessageBox::critical(0, tr("Error"),
- tr("Invalid return data at line %1: %2.")
- .arg(line)
- .arg( error_text));
- bd_.upgradeErrors++;
- return;
- }
-
- QString response;
- QString upgradeText;
-
- if (testing)
- currentVersion = "1.3.1"; // for testing
-
- bool allowBeta = true; // TODO: come from prefs or current version...
-
- QDomNodeList upgrades = document.elementsByTagName("update");
- QUrl downloadUrl;
- updateStatus_ = updateCurrent; // Current until proven guilty.
-
- for (unsigned int i = 0; i < upgrades.length(); i++) {
- QDomNode upgradeNode = upgrades.item(i);
- QDomElement upgrade = upgradeNode.toElement();
-
- QString updateVersion = upgrade.attribute("version");
- if (upgrade.attribute("downloadURL").isEmpty()) {
- downloadUrl = "http://www.gpsbabel.org/download.html";
- } else {
- downloadUrl = upgrade.attribute("downloadURL");
- }
- bool updateIsBeta = upgrade.attribute("type") == "beta";
- bool updateIsMajor = upgrade.attribute("type") == "major";
- bool updateIsMinor = upgrade.attribute("type") == "minor";
-
- bool updateCandidate = updateIsMajor || updateIsMinor || (updateIsBeta && allowBeta);
- upgradeText = upgrade.firstChildElement("overview").text();
- // String compare, not a numeric one. Server will return "best first".
- if((updateVersion > currentVersion) && updateCandidate) {
- bd_.upgradeOffers++;
- updateStatus_ = updateNeeded;
- response = tr("A new version of GPSBabel is available.<br />"
- "Your version is %1 <br />"
- "The latest version is %2")
- .arg(currentVersion)
- .arg(updateVersion);
- break;
- }
- }
-
- if (response.length()) {
- QMessageBox information;
- information.setWindowTitle(tr("Upgrade"));
-
- information.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- information.setDefaultButton(QMessageBox::Yes);
- information.setText(response);
-
- information.setInformativeText(tr("Do you wish to download an upgrade?"));
- information.setDetailedText(upgradeText);
-
- switch (information.exec()) {
- case QMessageBox::Yes:
- // downloadUrl.addQueryItem("os", getOsName());
- QDesktopServices::openUrl(downloadUrl);
- bd_.upgradeAccept++;
- break;
- default: ;
- bd_.upgradeDeclines++;
- }
- }
-
- upgradeWarningTime = QDateTime(QDateTime::currentDateTime());
-
- for (int i = 0; i < formatList_.size(); i++) {
- formatList_[i].zeroUseCounts();
- }
-}
--- /dev/null
+// -*- C++ -*-
+//------------------------------------------------------------------------
+//
+// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
+// USA
+//
+
+#include "version_mismatch.h"
+
+VersionMismatch::VersionMismatch(QWidget *parent, const QString &ver1,
+ const QString &ver2): QDialog(parent)
+{
+ ui.setupUi(this);
+
+ ui.ClVersion->setText(ver1);
+ ui.ClVersion->adjustSize();
+
+ ui.GuiVersion->setText(ver2);
+ ui.GuiVersion->adjustSize();
+}
+++ /dev/null
-// -*- C++ -*-
-//------------------------------------------------------------------------
-//
-// Copyright (C) 2010 Robert Lipe <robertlipe@gpsbabel.org
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111
-// USA
-//
-
-#include "version_mismatch.h"
-
-VersionMismatch::VersionMismatch(QWidget *parent, const QString &ver1,
- const QString &ver2): QDialog(parent)
-{
- ui.setupUi(this);
-
- ui.ClVersion->setText(ver1);
- ui.ClVersion->adjustSize();
-
- ui.GuiVersion->setText(ver2);
- ui.GuiVersion->adjustSize();
-}